From 7adf044e89a75b47c9f1388d5a2233bf9cdfcb07 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 24 Mar 2024 12:08:13 +0000 Subject: [PATCH] deploy: fbfdc7784e1bd0e640da75610c9d63949f3e4ba2 --- 404.html | 10 ++++----- assets/js/0be36c6e.263aeb23.js | 1 - assets/js/0be36c6e.627047f2.js | 1 + assets/js/0e384e19.0e880dff.js | 1 + assets/js/0e384e19.e32aa872.js | 1 - assets/js/0f881721.d2a951bb.js | 1 + assets/js/0f881721.f8e95083.js | 1 - assets/js/12193896.5b738686.js | 1 + assets/js/12193896.cf39a8ea.js | 1 - assets/js/3164f9fb.281a5b03.js | 1 + assets/js/3164f9fb.d0740bee.js | 1 - assets/js/3679e0b2.65ca3eef.js | 1 + assets/js/3679e0b2.d36cab8d.js | 1 - assets/js/4315fc58.04756219.js | 1 + assets/js/4315fc58.bc93d473.js | 1 - assets/js/46e25335.77249d93.js | 1 + assets/js/46e25335.d83f8ae7.js | 1 - assets/js/61036be0.b3bc9242.js | 1 - assets/js/61036be0.c52ea3e6.js | 1 + assets/js/693aa6a8.43876ded.js | 1 + assets/js/693aa6a8.6c33d6d2.js | 1 - assets/js/7d528a0b.3ed94e94.js | 1 + assets/js/7d528a0b.e6701fa1.js | 1 - ...f3328.3297c513.js => 814f3328.dcabf658.js} | 2 +- assets/js/91cb3e84.5866b4f7.js | 1 - assets/js/91cb3e84.5acf482c.js | 1 + assets/js/935f2afb.5006d101.js | 1 + assets/js/935f2afb.6c981c69.js | 1 - assets/js/9a119d2a.ff84d629.js | 1 - assets/js/a7023ddc.0176f139.js | 1 - assets/js/b204be58.580218a5.js | 1 - assets/js/b204be58.5f262826.js | 1 + assets/js/b2b675dd.e4ac76a4.js | 1 - assets/js/b2f554cd.44cb7583.js | 1 - assets/js/b745e581.233e377a.js | 1 - assets/js/ba59bd01.86a404f3.js | 1 + assets/js/bde67976.326724d7.js | 1 + assets/js/bde67976.5934ae8a.js | 1 - assets/js/c5039d34.1f98e805.js | 1 + assets/js/c5039d34.73855edb.js | 1 - assets/js/c9cd16d1.15d0e772.js | 1 - assets/js/c9cd16d1.ccdfc422.js | 1 + assets/js/c9e852ed.433dbfc2.js | 1 + assets/js/cd2705ba.af492360.js | 1 + assets/js/d321bdfd.324af267.js | 1 - assets/js/d321bdfd.707b2e80.js | 1 + assets/js/d86380de.5369d551.js | 1 + assets/js/d8d6d394.b5a6885d.js | 1 + assets/js/main.344f4c73.js | 2 -- assets/js/main.47ee4439.js | 2 ++ ...CENSE.txt => main.47ee4439.js.LICENSE.txt} | 0 assets/js/runtime~main.aade9a94.js | 1 + assets/js/runtime~main.bc8519de.js | 1 - blog/archive/index.html | 10 ++++----- blog/atom.xml | 10 ++++----- blog/first-blog-post/index.html | 12 +++++----- blog/index.html | 12 +++++----- blog/rss.xml | 6 ++--- blog/tags/first/index.html | 12 +++++----- blog/tags/index.html | 10 ++++----- docs/APIs/Fmath/index.html | 12 +++++----- docs/APIs/PewPew/index.html | 12 +++++----- docs/APIs/standard-libraries/index.html | 12 +++++----- docs/APIs/types/index.html | 12 +++++----- .../manifest-files/index.html | 12 +++++----- docs/File Information/mesh-files/index.html | 12 +++++----- docs/File Information/sound-files/index.html | 12 +++++----- docs/Guides/Lua/advanced/index.html | 12 +++++----- docs/Guides/Lua/beginner/index.html | 12 +++++----- docs/Guides/Lua/intermediate/index.html | 12 +++++----- docs/Guides/Other/fps-animation/index.html | 12 +++++----- docs/intro/index.html | 22 +++++++++---------- docs/other/level-design-principles/index.html | 12 +++++----- docs/other/level-restrictions/index.html | 12 +++++----- docs/other/trivia/index.html | 12 +++++----- index.html | 10 ++++----- search-index.json | 2 +- search/index.html | 10 ++++----- sitemap.xml | 2 +- 79 files changed, 175 insertions(+), 175 deletions(-) delete mode 100644 assets/js/0be36c6e.263aeb23.js create mode 100644 assets/js/0be36c6e.627047f2.js create mode 100644 assets/js/0e384e19.0e880dff.js delete mode 100644 assets/js/0e384e19.e32aa872.js create mode 100644 assets/js/0f881721.d2a951bb.js delete mode 100644 assets/js/0f881721.f8e95083.js create mode 100644 assets/js/12193896.5b738686.js delete mode 100644 assets/js/12193896.cf39a8ea.js create mode 100644 assets/js/3164f9fb.281a5b03.js delete mode 100644 assets/js/3164f9fb.d0740bee.js create mode 100644 assets/js/3679e0b2.65ca3eef.js delete mode 100644 assets/js/3679e0b2.d36cab8d.js create mode 100644 assets/js/4315fc58.04756219.js delete mode 100644 assets/js/4315fc58.bc93d473.js create mode 100644 assets/js/46e25335.77249d93.js delete mode 100644 assets/js/46e25335.d83f8ae7.js delete mode 100644 assets/js/61036be0.b3bc9242.js create mode 100644 assets/js/61036be0.c52ea3e6.js create mode 100644 assets/js/693aa6a8.43876ded.js delete mode 100644 assets/js/693aa6a8.6c33d6d2.js create mode 100644 assets/js/7d528a0b.3ed94e94.js delete mode 100644 assets/js/7d528a0b.e6701fa1.js rename assets/js/{814f3328.3297c513.js => 814f3328.dcabf658.js} (51%) delete mode 100644 assets/js/91cb3e84.5866b4f7.js create mode 100644 assets/js/91cb3e84.5acf482c.js create mode 100644 assets/js/935f2afb.5006d101.js delete mode 100644 assets/js/935f2afb.6c981c69.js delete mode 100644 assets/js/9a119d2a.ff84d629.js delete mode 100644 assets/js/a7023ddc.0176f139.js delete mode 100644 assets/js/b204be58.580218a5.js create mode 100644 assets/js/b204be58.5f262826.js delete mode 100644 assets/js/b2b675dd.e4ac76a4.js delete mode 100644 assets/js/b2f554cd.44cb7583.js delete mode 100644 assets/js/b745e581.233e377a.js create mode 100644 assets/js/ba59bd01.86a404f3.js create mode 100644 assets/js/bde67976.326724d7.js delete mode 100644 assets/js/bde67976.5934ae8a.js create mode 100644 assets/js/c5039d34.1f98e805.js delete mode 100644 assets/js/c5039d34.73855edb.js delete mode 100644 assets/js/c9cd16d1.15d0e772.js create mode 100644 assets/js/c9cd16d1.ccdfc422.js create mode 100644 assets/js/c9e852ed.433dbfc2.js create mode 100644 assets/js/cd2705ba.af492360.js delete mode 100644 assets/js/d321bdfd.324af267.js create mode 100644 assets/js/d321bdfd.707b2e80.js create mode 100644 assets/js/d86380de.5369d551.js create mode 100644 assets/js/d8d6d394.b5a6885d.js delete mode 100644 assets/js/main.344f4c73.js create mode 100644 assets/js/main.47ee4439.js rename assets/js/{main.344f4c73.js.LICENSE.txt => main.47ee4439.js.LICENSE.txt} (100%) create mode 100644 assets/js/runtime~main.aade9a94.js delete mode 100644 assets/js/runtime~main.bc8519de.js diff --git a/404.html b/404.html index fc253ed..dd65720 100644 --- a/404.html +++ b/404.html @@ -3,12 +3,12 @@ -Page Not Found | PPL Docs - - - +Page Not Found | PPL Docs + + + -
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

+
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

\ No newline at end of file diff --git a/assets/js/0be36c6e.263aeb23.js b/assets/js/0be36c6e.263aeb23.js deleted file mode 100644 index 4f9e89c..0000000 --- a/assets/js/0be36c6e.263aeb23.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[5559],{6304:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>u,frontMatter:()=>h,metadata:()=>r,toc:()=>c});var i=t(4848),a=t(8453),s=t(3554),o=t.n(s);const h={sidebar_position:1},l="60 FPS Animation",r={id:"Guides/Other/fps-animation",title:"60 FPS Animation",description:"Tutorial created by WinterNox.",source:"@site/docs/Guides/Other/60-fps-animation.mdx",sourceDirName:"Guides/Other",slug:"/Guides/Other/fps-animation",permalink:"/docs/Guides/Other/fps-animation",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/Guides/Other/60-fps-animation.mdx",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Advanced",permalink:"/docs/Guides/Lua/advanced"},next:{title:"Design principles",permalink:"/docs/other/level-design-principles"}},d={},c=[{value:"YouTube tutorial",id:"youtube-tutorial",level:3},{value:"Mesh animations",id:"mesh-animations",level:3},{value:"Limitations",id:"limitations",level:3},{value:"Setting up",id:"setting-up",level:3},{value:"Getting started",id:"getting-started",level:3},{value:"Making the mesh",id:"making-the-mesh",level:4},{value:"Creating the entity and assigning it the mesh",id:"creating-the-entity-and-assigning-it-the-mesh",level:4},{value:"Animating the mesh",id:"animating-the-mesh",level:3},{value:"Making the animation 60 FPS",id:"making-the-animation-60-fps",level:3}];function m(e){const n={a:"a",code:"code",em:"em",h1:"h1",h3:"h3",h4:"h4",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"60-fps-animation",children:"60 FPS Animation"}),"\n",(0,i.jsxs)(n.p,{children:["Tutorial created by ",(0,i.jsx)(n.a,{href:"https://github.com/WinterNox",children:"WinterNox"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"youtube-tutorial",children:"YouTube tutorial"}),"\n",(0,i.jsx)("iframe",{src:"//www.youtube.com/embed/145kDy9nr3E",frameborder:"0",allowfullscreen:!0,width:"100%",height:"480px"}),"\n",(0,i.jsx)(n.h3,{id:"mesh-animations",children:"Mesh animations"}),"\n",(0,i.jsx)(n.p,{children:"Mesh animations in PewPew Live are achieved by iterating through multiple meshes that are slightly different from each other. The meshes are usually stored in a single file and are made procedurally."}),"\n",(0,i.jsx)(n.h3,{id:"limitations",children:"Limitations"}),"\n",(0,i.jsx)(n.p,{children:"If you have some experience with level creation, you should know that PewPew Live runs at 30 ticks per second and that the graphics are interpolated. However, the interpolation only applies to transformations (position, rotation and scale). But, what about mesh animations? Since you can only change something about the entity per tick, mesh animations would be limited to 30 frames per second. Thankfully, the PPL Lua API has just the right function that can be used to achieve 60 FPS mesh animations. This function is:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"pewpew.customizable_entity_set_flipping_meshes(entity_id, file_path, index1, index2)\n"})}),"\n",(0,i.jsx)(n.p,{children:"When used, the entity will switch between the two specified meshes in a single game tick. But, how does that help us achieve 60 FPS animations? Let's see."}),"\n",(0,i.jsx)(n.h3,{id:"setting-up",children:"Setting up"}),"\n",(0,i.jsxs)(n.p,{children:["Before we can start making an animation and assigning it to an entity, we need to have a base level that we can work with.\nStart by creating a new folder in ",(0,i.jsx)(n.code,{children:"./content/levels/"}),". In the newly created folder, make sure you have these files:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"level.lua"})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"graphics.lua"})," (The name of your mesh file can be different, but remember it!)"]}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"manifest.json"})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you need a basic ",(0,i.jsx)(n.code,{children:"manifest.json"}),", here is a template you can use."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "name": "60 FPS",\n "descriptions": ["Amazing"],\n "entry_point": "level.lua",\n "has_score_leaderboard": false\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"getting-started",children:"Getting started"}),"\n",(0,i.jsxs)(n.p,{children:["Now that we have a level base, we can start making our mesh and entity. If at any point you face a problem, try following the steps again, or check the ",(0,i.jsxs)(n.a,{href:"https://github.com/pewpewlive/ppl-utils/tree/master/content/levels/sample_animation",children:["final ",(0,i.jsx)(n.code,{children:".lua"})," files"]}),"."]}),"\n",(0,i.jsx)(n.h4,{id:"making-the-mesh",children:"Making the mesh"}),"\n",(0,i.jsxs)(n.p,{children:["Open ",(0,i.jsx)(n.code,{children:"graphics.lua"})," (or your mesh file) and start by writing the following:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"meshes = {}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Since our meshes are going to be procedurally generated, we won't be making every vertex by hand, instead, we will make Lua do that for us! Essentially when making a procedural mesh, we make a table with our vertexes and segments, that we later add to the ",(0,i.jsx)(n.code,{children:"meshes"})," table. The vertex and segment tables are going to hold the generated points and segment indexes."]}),"\n",(0,i.jsx)(n.p,{children:"Add this to your mesh file:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"-- Tables for our mesh vertexes, segments\nlocal computed_vertexes, computed_segments = {}, {}\n"})}),"\n",(0,i.jsx)(n.p,{children:"Now we need a way to populate the tables with our mesh points and segments."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.em,{children:"Note: In this example, we will be making a hexagon!"})}),"\n",(0,i.jsxs)(n.p,{children:["Start by defining the ",(0,i.jsx)(n.code,{children:"radius"})," and ",(0,i.jsx)(n.code,{children:"small_radius"})," variables. They will be used when generating the hexagon sides. Also, create a variable ",(0,i.jsx)(n.code,{children:"i"}),", which will be used for the segments. Now, create a for loop that will go from ",(0,i.jsx)(n.code,{children:"0"})," to ",(0,i.jsx)(n.code,{children:"math.pi * 2"})," and increment by ",(0,i.jsx)(n.code,{children:"math.pi * 2 / 6"})," (since we want it to be a hexagon). Get the corresponding sine and cosine of the angle (y and x positions). Multiply one pair by the default radius and one by the smaller radius, and add them to the vertexes table. To add the needed segment indexes, we need to connect the vertexes together. Connect the inner hexagon vertex to the outer one, connect the inner hexagon vertex with its own next vertex, and connect the outer hexagon vertex the same way. Increment the segment counter by 2."]}),"\n",(0,i.jsx)(n.p,{children:"The resulting code should look something like this:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local radius = 96 -- Outer hexagon\nlocal small_radius = 48 -- Inner hexagon\n\nlocal i = 0\nfor angle = 0, math.pi * 2, math.pi * 2 / 6 do -- We want to go from angle 0 to 2\u03c0, skipping by 2\u03c0 / 6, making a hexagon\n local y, x = math.sincos(angle) -- y and x positions on the unit circle\n\n table.insert(computed_vertexes, {x * radius, y * radius}) -- Vertex for the outer hexagon\n table.insert(computed_vertexes, {x * small_radius, y * small_radius}) -- Vertex for the inner hexagon\n\n table.insert(computed_segments, {i, i + 1}) -- Line joining the corresponding vertices of the inner and outer hexagons\n table.insert(computed_segments, {i, i + 2}) -- Line joining the vertex of the outer hexagon to its next one\n table.insert(computed_segments, {i + 1, i + 3}) -- Line joining the vertex of the inner hexagon to its next one\n\n i = i + 2\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Because of the way we added the segments, at the end of the for loop we get extra segments that are unnecessary. After the for loop, we can remove them by doing this:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"table.remove(computed_segments, #computed_segments) -- Removal of the last segment as there is no vertex at index i + 3 during the last iteration\ntable.remove(computed_segments, #computed_segments) -- No vertex at index i + 2 during the last iteration\ntable.remove(computed_segments, #computed_segments) -- A line is already present joining the vertices\n"})}),"\n",(0,i.jsx)(n.p,{children:"At the end, we add the mesh made up of the generated vertexes and segments."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"table.insert(meshes, {\n vertexes = computed_vertexes,\n segments = computed_segments\n})\n"})}),"\n",(0,i.jsx)(n.h4,{id:"creating-the-entity-and-assigning-it-the-mesh",children:"Creating the entity and assigning it the mesh"}),"\n",(0,i.jsxs)(n.p,{children:["Now, go to ",(0,i.jsx)(n.code,{children:"level.lua"}),", and start by creating an entity at position ",(0,i.jsx)(n.code,{children:"(0fx, 0fx)"}),". Next, set the entity's mesh to the one we just created."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'local id = pewpew.new_customizable_entity(0fx, 0fx)\npewpew.customizable_entity_set_mesh(id, "/dynamic/graphics.lua", 0) -- Change the filename if needed\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.em,{children:"Note: Setting level size and creating a player is optional."})}),"\n",(0,i.jsxs)(n.p,{children:["Run ",(0,i.jsx)(n.code,{children:"ppl-utils.exe"})," and open your level at ",(0,i.jsx)(n.a,{href:"http://localhost:9000/pewpew.html",children:"http://localhost:9000/pewpew.html"})]}),"\n",(0,i.jsxs)(n.p,{children:["You should see the following:\n",(0,i.jsx)(n.img,{src:"https://github.com/pewpewlive/ppl-utils/assets/42890752/10aa6ab4-46cb-4798-b8f8-a72435d42b32",alt:"Initial mesh"})]}),"\n",(0,i.jsx)(n.p,{children:"If you don't, you might have made a mistake somewhere! Check the steps to make the mesh again and check for mistakes."}),"\n",(0,i.jsx)(n.h3,{id:"animating-the-mesh",children:"Animating the mesh"}),"\n",(0,i.jsx)(n.p,{children:"Let's get into animating our mesh! For this tutorial, we will have the outer hexagon rotating clockwise and the inner hexagon counterclockwise."}),"\n",(0,i.jsx)(n.p,{children:'To do this, we need multiple "meshes" that we will set our entity to.'}),"\n",(0,i.jsx)(n.p,{children:"In your mesh file, change for loop to the following:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"for angle_offset = 0, math.pi * 2, math.pi * 2 / 60 do -- Our animation will have 60 frames. We want the hexagons to make a full rotation each 60 frames (2 seconds). This does not mean the animation is 60FPS yet!\n -- Tables for our mesh vertexes, segments\n local computed_vertexes, computed_segments = {}, {}\n\n local radius = 96 -- Outer hexagon\n local small_radius = 48 -- Inner hexagon\n\n local i = 0\n for angle = 0, math.pi * 2, math.pi * 2 / 6 do -- We want to go from angle 0 to 2\u03c0, skipping by 2\u03c0 / 6, making a hexagon\n local y, x = math.sincos(angle) -- y and x positions on the unit circle\n\n table.insert(computed_vertexes, {x * radius, y * radius}) -- Vertex for the outer hexagon\n table.insert(computed_vertexes, {x * small_radius, y * small_radius}) -- Vertex for the inner hexagon\n\n table.insert(computed_segments, {i, i + 1}) -- Line joining the corresponding vertices of the inner and outer hexagons\n table.insert(computed_segments, {i, i + 2}) -- Line joining the vertex of the outer hexagon to its next one\n table.insert(computed_segments, {i + 1, i + 3}) -- Line joining the vertex of the inner hexagon to its next one\n\n i = i + 2\n end\n\n table.remove(computed_segments, #computed_segments) -- Removal of the last segment as there is no vertex at index i + 3 during the last iteration\n table.remove(computed_segments, #computed_segments) -- No vertex at index i + 2 during the last iteration\n table.remove(computed_segments, #computed_segments) -- A line is already present joining the vertices\n\n table.insert(meshes, {\n vertexes = computed_vertexes,\n segments = computed_segments\n })\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"As you can see, the real mesh generation code is pretty much the same, just that we repeat it several times instead, making it have frames!"}),"\n",(0,i.jsx)(n.p,{children:"Now, most importantly, we need to change the way we get the points of our hexagon. Since we want the outer hexagon to turn clockwise and the inner one counterclockwise, we need to change the angles depending on which frame we are on. Since each frame is going to have a specific angle offset, we can add that to our initial angles, meaning we have to change this line:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local y, x = math.sincos(angle)\n"})}),"\n",(0,i.jsx)(n.p,{children:"into"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local y, x = math.sincos(angle - angle_offset)\n"})}),"\n",(0,i.jsx)(n.p,{children:"And add a new line below it like so:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local y2, x2 = math.sincos(angle + angle_offset)\n"})}),"\n",(0,i.jsxs)(n.p,{children:["We will use ",(0,i.jsx)(n.code,{children:"x2"})," and ",(0,i.jsx)(n.code,{children:"y2"})," for the inner hexagon. To do this, replace the ",(0,i.jsx)(n.code,{children:"x * small_radius"})," and ",(0,i.jsx)(n.code,{children:"y * small_radius"})," coordinates for the inner hexagon with ",(0,i.jsx)(n.code,{children:"x2 * small_radius"})," and ",(0,i.jsx)(n.code,{children:"y2 * small_radius"})," respectively."]}),"\n",(0,i.jsxs)(n.p,{children:["We now have 60 frames of meshes that we can use to animate our entity. To do this, we need to use an index which will increase every tick, and use that to set the entity's mesh. This can be done like so:\nIn ",(0,i.jsx)(n.code,{children:"level.lua"}),", replace the second line with this code:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'local mesh_index = 0\npewpew.entity_set_update_callback(id, function()\n -- We have 60 frames out of 61 total frames. The last frame is equal to the first one and is unused.\n -- The index of the 60th frame is 59. (Although we are using lua, mesh and sound indexes start from 0 in PewPew Lib API.)\n -- Loop when we have exceeded past the last frame.\n if mesh_index > 59 then\n mesh_index = 0\n end\n\n pewpew.customizable_entity_set_mesh(id, "/dynamic/graphics.lua", mesh_index)\n mesh_index = mesh_index + 1\nend)\n'})}),"\n",(0,i.jsx)(n.p,{children:"The code is pretty self-explanatory. We increment the index every tick and use that index to set the mesh. Since the meshes we have generated have small changes in them, doing this creates an animation."}),"\n",(0,i.jsx)(n.p,{children:"The result should look something like this:"}),"\n",(0,i.jsx)(o(),{controls:!0,playing:!0,loop:!0,url:"https://github.com/pewpewlive/ppl-utils/assets/42890752/5a2c1a1c-d079-4497-ab83-deca095ca01a"}),"\n",(0,i.jsx)(n.p,{children:"As you can see, it is an animation. Though, this animation is running at only 30 frames per second. This is an issue. An animation running at 30 FPS will not look good with the rest of the level as the level might have other content that moves. And as you already know, position transformation is interpolated by PewPew Live. This means that, even though the level runs at 30 ticks per second, the game will interpolate the graphics and display them at 60 FPS or 90 FPS for example. (The game interpolates the graphics as per the refresh rate of the device, which will usually be higher than 30Hz.) To ensure that the difference between the rest of the level and our mesh animation is minimal, we have to make our mesh animation run on at least 60 FPS."}),"\n",(0,i.jsx)(n.h3,{id:"making-the-animation-60-fps",children:"Making the animation 60 FPS"}),"\n",(0,i.jsx)(n.p,{children:"Open your mesh file and replace the line"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"for angle_offset = 0, math.pi * 2, math.pi * 2 / 60 do -- 60\n -- Code that generates the meshes\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"with"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"for angle_offset = 0, math.pi * 2, math.pi * 2 / 120 do -- 120\n -- Code that generates the meshes\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"The new code will create 121 frames or meshes for us, out of which 120 will be used. (This is because the last and first frames are the same.)"}),"\n",(0,i.jsx)(n.p,{children:"If you save the files and run your level, you might notice that the animation is getting reset halfway through. This is because at the 60th frame, we have gone only 50% through the animation."}),"\n",(0,i.jsxs)(n.p,{children:["Since we now have 120 frames, we need to change the code in ",(0,i.jsx)(n.code,{children:"level.lua"})," to account for this change. Open ",(0,i.jsx)(n.code,{children:"level.lua"})," and change the line"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"if mesh_index > 59 then\n mesh_index = 0\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"to"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"if mesh_index > 119 then\n mesh_index = 0\nend\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The new code now shows the complete animation when running the level. However, it is visibly slower. Why is this the case? Remember, in the previous case, the variable ",(0,i.jsx)(n.code,{children:"angle_offset"})," was increasing by ",(0,i.jsx)(n.code,{children:"2\u03c0/60"})," every frame. Now, it is increasing by ",(0,i.jsx)(n.code,{children:"2\u03c0/120"})," every frame. You might be wondering why we did this. This is because to achieve a 60 FPS animation that runs with the same speed, we need to have double the amount of frames that we had previously. We now just need to speed the animation back to its original speed."]}),"\n",(0,i.jsxs)(n.p,{children:["Open ",(0,i.jsx)(n.code,{children:"level.lua"})," and change"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"mesh_index = mesh_index + 1\n"})}),"\n",(0,i.jsx)(n.p,{children:"to"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"mesh_index = mesh_index + 2\n"})}),"\n",(0,i.jsx)(n.p,{children:"This should make the animation return to its original speed, as we are skipping every other frame. However, if you save the files and run your level, you will notice no change between the current animation and the one we had at the start. You would in fact be right, there is no difference between the two. Our animation still runs at 30 FPS. This is where flipping meshes comes into play."}),"\n",(0,i.jsxs)(n.p,{children:["Open ",(0,i.jsx)(n.code,{children:"level.lua"})," and replace"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'pewpew.customizable_entity_set_mesh(id, "/dynamic/graphics.lua", mesh_index)\n'})}),"\n",(0,i.jsx)(n.p,{children:"with"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'pewpew.customizable_entity_set_flipping_meshes(id, "/dynamic/graphics.lua", mesh_index, mesh_index + 1)\n'})}),"\n",(0,i.jsxs)(n.p,{children:["What does this exactly do? When we set flipping meshes of an entity, that entity goes over the two specified meshes in a single game tick. This means that, in the first game tick, it will have the mesh at ",(0,i.jsx)(n.code,{children:"index 0"})," for half a tick and will have the mesh at ",(0,i.jsx)(n.code,{children:"index 1"})," for the rest half of a tick. In the next tick, we are resetting the flipping meshes. The variable ",(0,i.jsx)(n.code,{children:"mesh_index"})," now has a value of ",(0,i.jsx)(n.code,{children:"2"}),". The entity now has the mesh at ",(0,i.jsx)(n.code,{children:"index 2"})," for half a tick and has the mesh at ",(0,i.jsx)(n.code,{children:"index 3"})," for half a tick. Notice that we have gone over 4 meshes in just 2 game ticks (2 meshes per game tick)! The way in which we have used this creates an animation that runs at 60 FPS. Now, if you ",(0,i.jsx)(n.strong,{children:"save the files and run your level"}),", you'll notice that it is a lot smoother than our initial animation. It is exactly twice as smooth. It might look something like this:"]}),"\n",(0,i.jsx)(o(),{controls:!0,playing:!0,loop:!0,url:"https://github.com/pewpewlive/ppl-utils/assets/42890752/342de310-cc7b-4b4b-8c35-5cf34d078ad0"}),"\n",(0,i.jsx)(n.p,{children:"Congratulations! You have successfully made an animation that runs at 60 frames per second. I hope that you were able to understand this fairly well. Now, experiment with your code and make creative animations."})]})}function u(e={}){const{wrapper:n}={...(0,a.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(m,{...e})}):m(e)}}}]); \ No newline at end of file diff --git a/assets/js/0be36c6e.627047f2.js b/assets/js/0be36c6e.627047f2.js new file mode 100644 index 0000000..d818519 --- /dev/null +++ b/assets/js/0be36c6e.627047f2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[5559],{6304:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>l,default:()=>u,frontMatter:()=>h,metadata:()=>r,toc:()=>c});var i=t(4848),s=t(8453),a=t(3554),o=t.n(a);const h={sidebar_position:1},l="60 FPS Animation",r={id:"Guides/Other/fps-animation",title:"60 FPS Animation",description:"Tutorial created by WinterNox.",source:"@site/docs/Guides/Other/60-fps-animation.mdx",sourceDirName:"Guides/Other",slug:"/Guides/Other/fps-animation",permalink:"/ppl-docs/docs/Guides/Other/fps-animation",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/Guides/Other/60-fps-animation.mdx",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Advanced",permalink:"/ppl-docs/docs/Guides/Lua/advanced"},next:{title:"Design principles",permalink:"/ppl-docs/docs/other/level-design-principles"}},d={},c=[{value:"YouTube tutorial",id:"youtube-tutorial",level:3},{value:"Mesh animations",id:"mesh-animations",level:3},{value:"Limitations",id:"limitations",level:3},{value:"Setting up",id:"setting-up",level:3},{value:"Getting started",id:"getting-started",level:3},{value:"Making the mesh",id:"making-the-mesh",level:4},{value:"Creating the entity and assigning it the mesh",id:"creating-the-entity-and-assigning-it-the-mesh",level:4},{value:"Animating the mesh",id:"animating-the-mesh",level:3},{value:"Making the animation 60 FPS",id:"making-the-animation-60-fps",level:3}];function m(e){const n={a:"a",code:"code",em:"em",h1:"h1",h3:"h3",h4:"h4",img:"img",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"60-fps-animation",children:"60 FPS Animation"}),"\n",(0,i.jsxs)(n.p,{children:["Tutorial created by ",(0,i.jsx)(n.a,{href:"https://github.com/WinterNox",children:"WinterNox"}),"."]}),"\n",(0,i.jsx)(n.h3,{id:"youtube-tutorial",children:"YouTube tutorial"}),"\n",(0,i.jsx)("iframe",{src:"//www.youtube.com/embed/145kDy9nr3E",frameborder:"0",allowfullscreen:!0,width:"100%",height:"480px"}),"\n",(0,i.jsx)(n.h3,{id:"mesh-animations",children:"Mesh animations"}),"\n",(0,i.jsx)(n.p,{children:"Mesh animations in PewPew Live are achieved by iterating through multiple meshes that are slightly different from each other. The meshes are usually stored in a single file and are made procedurally."}),"\n",(0,i.jsx)(n.h3,{id:"limitations",children:"Limitations"}),"\n",(0,i.jsx)(n.p,{children:"If you have some experience with level creation, you should know that PewPew Live runs at 30 ticks per second and that the graphics are interpolated. However, the interpolation only applies to transformations (position, rotation and scale). But, what about mesh animations? Since you can only change something about the entity per tick, mesh animations would be limited to 30 frames per second. Thankfully, the PPL Lua API has just the right function that can be used to achieve 60 FPS mesh animations. This function is:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"pewpew.customizable_entity_set_flipping_meshes(entity_id, file_path, index1, index2)\n"})}),"\n",(0,i.jsx)(n.p,{children:"When used, the entity will switch between the two specified meshes in a single game tick. But, how does that help us achieve 60 FPS animations? Let's see."}),"\n",(0,i.jsx)(n.h3,{id:"setting-up",children:"Setting up"}),"\n",(0,i.jsxs)(n.p,{children:["Before we can start making an animation and assigning it to an entity, we need to have a base level that we can work with.\nStart by creating a new folder in ",(0,i.jsx)(n.code,{children:"./content/levels/"}),". In the newly created folder, make sure you have these files:"]}),"\n",(0,i.jsxs)(n.ul,{children:["\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"level.lua"})}),"\n",(0,i.jsxs)(n.li,{children:[(0,i.jsx)(n.code,{children:"graphics.lua"})," (The name of your mesh file can be different, but remember it!)"]}),"\n",(0,i.jsx)(n.li,{children:(0,i.jsx)(n.code,{children:"manifest.json"})}),"\n"]}),"\n",(0,i.jsxs)(n.p,{children:["If you need a basic ",(0,i.jsx)(n.code,{children:"manifest.json"}),", here is a template you can use."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-json",children:'{\n "name": "60 FPS",\n "descriptions": ["Amazing"],\n "entry_point": "level.lua",\n "has_score_leaderboard": false\n}\n'})}),"\n",(0,i.jsx)(n.h3,{id:"getting-started",children:"Getting started"}),"\n",(0,i.jsxs)(n.p,{children:["Now that we have a level base, we can start making our mesh and entity. If at any point you face a problem, try following the steps again, or check the ",(0,i.jsxs)(n.a,{href:"https://github.com/pewpewlive/ppl-utils/tree/master/content/levels/sample_animation",children:["final ",(0,i.jsx)(n.code,{children:".lua"})," files"]}),"."]}),"\n",(0,i.jsx)(n.h4,{id:"making-the-mesh",children:"Making the mesh"}),"\n",(0,i.jsxs)(n.p,{children:["Open ",(0,i.jsx)(n.code,{children:"graphics.lua"})," (or your mesh file) and start by writing the following:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"meshes = {}\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Since our meshes are going to be procedurally generated, we won't be making every vertex by hand, instead, we will make Lua do that for us! Essentially when making a procedural mesh, we make a table with our vertexes and segments, that we later add to the ",(0,i.jsx)(n.code,{children:"meshes"})," table. The vertex and segment tables are going to hold the generated points and segment indexes."]}),"\n",(0,i.jsx)(n.p,{children:"Add this to your mesh file:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"-- Tables for our mesh vertexes, segments\nlocal computed_vertexes, computed_segments = {}, {}\n"})}),"\n",(0,i.jsx)(n.p,{children:"Now we need a way to populate the tables with our mesh points and segments."}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.em,{children:"Note: In this example, we will be making a hexagon!"})}),"\n",(0,i.jsxs)(n.p,{children:["Start by defining the ",(0,i.jsx)(n.code,{children:"radius"})," and ",(0,i.jsx)(n.code,{children:"small_radius"})," variables. They will be used when generating the hexagon sides. Also, create a variable ",(0,i.jsx)(n.code,{children:"i"}),", which will be used for the segments. Now, create a for loop that will go from ",(0,i.jsx)(n.code,{children:"0"})," to ",(0,i.jsx)(n.code,{children:"math.pi * 2"})," and increment by ",(0,i.jsx)(n.code,{children:"math.pi * 2 / 6"})," (since we want it to be a hexagon). Get the corresponding sine and cosine of the angle (y and x positions). Multiply one pair by the default radius and one by the smaller radius, and add them to the vertexes table. To add the needed segment indexes, we need to connect the vertexes together. Connect the inner hexagon vertex to the outer one, connect the inner hexagon vertex with its own next vertex, and connect the outer hexagon vertex the same way. Increment the segment counter by 2."]}),"\n",(0,i.jsx)(n.p,{children:"The resulting code should look something like this:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local radius = 96 -- Outer hexagon\nlocal small_radius = 48 -- Inner hexagon\n\nlocal i = 0\nfor angle = 0, math.pi * 2, math.pi * 2 / 6 do -- We want to go from angle 0 to 2\u03c0, skipping by 2\u03c0 / 6, making a hexagon\n local y, x = math.sincos(angle) -- y and x positions on the unit circle\n\n table.insert(computed_vertexes, {x * radius, y * radius}) -- Vertex for the outer hexagon\n table.insert(computed_vertexes, {x * small_radius, y * small_radius}) -- Vertex for the inner hexagon\n\n table.insert(computed_segments, {i, i + 1}) -- Line joining the corresponding vertices of the inner and outer hexagons\n table.insert(computed_segments, {i, i + 2}) -- Line joining the vertex of the outer hexagon to its next one\n table.insert(computed_segments, {i + 1, i + 3}) -- Line joining the vertex of the inner hexagon to its next one\n\n i = i + 2\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Because of the way we added the segments, at the end of the for loop we get extra segments that are unnecessary. After the for loop, we can remove them by doing this:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"table.remove(computed_segments, #computed_segments) -- Removal of the last segment as there is no vertex at index i + 3 during the last iteration\ntable.remove(computed_segments, #computed_segments) -- No vertex at index i + 2 during the last iteration\ntable.remove(computed_segments, #computed_segments) -- A line is already present joining the vertices\n"})}),"\n",(0,i.jsx)(n.p,{children:"At the end, we add the mesh made up of the generated vertexes and segments."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"table.insert(meshes, {\n vertexes = computed_vertexes,\n segments = computed_segments\n})\n"})}),"\n",(0,i.jsx)(n.h4,{id:"creating-the-entity-and-assigning-it-the-mesh",children:"Creating the entity and assigning it the mesh"}),"\n",(0,i.jsxs)(n.p,{children:["Now, go to ",(0,i.jsx)(n.code,{children:"level.lua"}),", and start by creating an entity at position ",(0,i.jsx)(n.code,{children:"(0fx, 0fx)"}),". Next, set the entity's mesh to the one we just created."]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'local id = pewpew.new_customizable_entity(0fx, 0fx)\npewpew.customizable_entity_set_mesh(id, "/dynamic/graphics.lua", 0) -- Change the filename if needed\n'})}),"\n",(0,i.jsx)(n.p,{children:(0,i.jsx)(n.em,{children:"Note: Setting level size and creating a player is optional."})}),"\n",(0,i.jsxs)(n.p,{children:["Run ",(0,i.jsx)(n.code,{children:"ppl-utils.exe"})," and open your level at ",(0,i.jsx)(n.a,{href:"http://localhost:9000/pewpew.html",children:"http://localhost:9000/pewpew.html"})]}),"\n",(0,i.jsxs)(n.p,{children:["You should see the following:\n",(0,i.jsx)(n.img,{src:"https://github.com/pewpewlive/ppl-utils/assets/42890752/10aa6ab4-46cb-4798-b8f8-a72435d42b32",alt:"Initial mesh"})]}),"\n",(0,i.jsx)(n.p,{children:"If you don't, you might have made a mistake somewhere! Check the steps to make the mesh again and check for mistakes."}),"\n",(0,i.jsx)(n.h3,{id:"animating-the-mesh",children:"Animating the mesh"}),"\n",(0,i.jsx)(n.p,{children:"Let's get into animating our mesh! For this tutorial, we will have the outer hexagon rotating clockwise and the inner hexagon counterclockwise."}),"\n",(0,i.jsx)(n.p,{children:'To do this, we need multiple "meshes" that we will set our entity to.'}),"\n",(0,i.jsx)(n.p,{children:"In your mesh file, change for loop to the following:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"for angle_offset = 0, math.pi * 2, math.pi * 2 / 60 do -- Our animation will have 60 frames. We want the hexagons to make a full rotation each 60 frames (2 seconds). This does not mean the animation is 60FPS yet!\n -- Tables for our mesh vertexes, segments\n local computed_vertexes, computed_segments = {}, {}\n\n local radius = 96 -- Outer hexagon\n local small_radius = 48 -- Inner hexagon\n\n local i = 0\n for angle = 0, math.pi * 2, math.pi * 2 / 6 do -- We want to go from angle 0 to 2\u03c0, skipping by 2\u03c0 / 6, making a hexagon\n local y, x = math.sincos(angle) -- y and x positions on the unit circle\n\n table.insert(computed_vertexes, {x * radius, y * radius}) -- Vertex for the outer hexagon\n table.insert(computed_vertexes, {x * small_radius, y * small_radius}) -- Vertex for the inner hexagon\n\n table.insert(computed_segments, {i, i + 1}) -- Line joining the corresponding vertices of the inner and outer hexagons\n table.insert(computed_segments, {i, i + 2}) -- Line joining the vertex of the outer hexagon to its next one\n table.insert(computed_segments, {i + 1, i + 3}) -- Line joining the vertex of the inner hexagon to its next one\n\n i = i + 2\n end\n\n table.remove(computed_segments, #computed_segments) -- Removal of the last segment as there is no vertex at index i + 3 during the last iteration\n table.remove(computed_segments, #computed_segments) -- No vertex at index i + 2 during the last iteration\n table.remove(computed_segments, #computed_segments) -- A line is already present joining the vertices\n\n table.insert(meshes, {\n vertexes = computed_vertexes,\n segments = computed_segments\n })\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"As you can see, the real mesh generation code is pretty much the same, just that we repeat it several times instead, making it have frames!"}),"\n",(0,i.jsx)(n.p,{children:"Now, most importantly, we need to change the way we get the points of our hexagon. Since we want the outer hexagon to turn clockwise and the inner one counterclockwise, we need to change the angles depending on which frame we are on. Since each frame is going to have a specific angle offset, we can add that to our initial angles, meaning we have to change this line:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local y, x = math.sincos(angle)\n"})}),"\n",(0,i.jsx)(n.p,{children:"into"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local y, x = math.sincos(angle - angle_offset)\n"})}),"\n",(0,i.jsx)(n.p,{children:"And add a new line below it like so:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local y2, x2 = math.sincos(angle + angle_offset)\n"})}),"\n",(0,i.jsxs)(n.p,{children:["We will use ",(0,i.jsx)(n.code,{children:"x2"})," and ",(0,i.jsx)(n.code,{children:"y2"})," for the inner hexagon. To do this, replace the ",(0,i.jsx)(n.code,{children:"x * small_radius"})," and ",(0,i.jsx)(n.code,{children:"y * small_radius"})," coordinates for the inner hexagon with ",(0,i.jsx)(n.code,{children:"x2 * small_radius"})," and ",(0,i.jsx)(n.code,{children:"y2 * small_radius"})," respectively."]}),"\n",(0,i.jsxs)(n.p,{children:["We now have 60 frames of meshes that we can use to animate our entity. To do this, we need to use an index which will increase every tick, and use that to set the entity's mesh. This can be done like so:\nIn ",(0,i.jsx)(n.code,{children:"level.lua"}),", replace the second line with this code:"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'local mesh_index = 0\npewpew.entity_set_update_callback(id, function()\n -- We have 60 frames out of 61 total frames. The last frame is equal to the first one and is unused.\n -- The index of the 60th frame is 59. (Although we are using lua, mesh and sound indexes start from 0 in PewPew Lib API.)\n -- Loop when we have exceeded past the last frame.\n if mesh_index > 59 then\n mesh_index = 0\n end\n\n pewpew.customizable_entity_set_mesh(id, "/dynamic/graphics.lua", mesh_index)\n mesh_index = mesh_index + 1\nend)\n'})}),"\n",(0,i.jsx)(n.p,{children:"The code is pretty self-explanatory. We increment the index every tick and use that index to set the mesh. Since the meshes we have generated have small changes in them, doing this creates an animation."}),"\n",(0,i.jsx)(n.p,{children:"The result should look something like this:"}),"\n",(0,i.jsx)(o(),{controls:!0,playing:!0,loop:!0,url:"https://github.com/pewpewlive/ppl-utils/assets/42890752/5a2c1a1c-d079-4497-ab83-deca095ca01a"}),"\n",(0,i.jsx)(n.p,{children:"As you can see, it is an animation. Though, this animation is running at only 30 frames per second. This is an issue. An animation running at 30 FPS will not look good with the rest of the level as the level might have other content that moves. And as you already know, position transformation is interpolated by PewPew Live. This means that, even though the level runs at 30 ticks per second, the game will interpolate the graphics and display them at 60 FPS or 90 FPS for example. (The game interpolates the graphics as per the refresh rate of the device, which will usually be higher than 30Hz.) To ensure that the difference between the rest of the level and our mesh animation is minimal, we have to make our mesh animation run on at least 60 FPS."}),"\n",(0,i.jsx)(n.h3,{id:"making-the-animation-60-fps",children:"Making the animation 60 FPS"}),"\n",(0,i.jsx)(n.p,{children:"Open your mesh file and replace the line"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"for angle_offset = 0, math.pi * 2, math.pi * 2 / 60 do -- 60\n -- Code that generates the meshes\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"with"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"for angle_offset = 0, math.pi * 2, math.pi * 2 / 120 do -- 120\n -- Code that generates the meshes\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"The new code will create 121 frames or meshes for us, out of which 120 will be used. (This is because the last and first frames are the same.)"}),"\n",(0,i.jsx)(n.p,{children:"If you save the files and run your level, you might notice that the animation is getting reset halfway through. This is because at the 60th frame, we have gone only 50% through the animation."}),"\n",(0,i.jsxs)(n.p,{children:["Since we now have 120 frames, we need to change the code in ",(0,i.jsx)(n.code,{children:"level.lua"})," to account for this change. Open ",(0,i.jsx)(n.code,{children:"level.lua"})," and change the line"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"if mesh_index > 59 then\n mesh_index = 0\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"to"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"if mesh_index > 119 then\n mesh_index = 0\nend\n"})}),"\n",(0,i.jsxs)(n.p,{children:["The new code now shows the complete animation when running the level. However, it is visibly slower. Why is this the case? Remember, in the previous case, the variable ",(0,i.jsx)(n.code,{children:"angle_offset"})," was increasing by ",(0,i.jsx)(n.code,{children:"2\u03c0/60"})," every frame. Now, it is increasing by ",(0,i.jsx)(n.code,{children:"2\u03c0/120"})," every frame. You might be wondering why we did this. This is because to achieve a 60 FPS animation that runs with the same speed, we need to have double the amount of frames that we had previously. We now just need to speed the animation back to its original speed."]}),"\n",(0,i.jsxs)(n.p,{children:["Open ",(0,i.jsx)(n.code,{children:"level.lua"})," and change"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"mesh_index = mesh_index + 1\n"})}),"\n",(0,i.jsx)(n.p,{children:"to"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"mesh_index = mesh_index + 2\n"})}),"\n",(0,i.jsx)(n.p,{children:"This should make the animation return to its original speed, as we are skipping every other frame. However, if you save the files and run your level, you will notice no change between the current animation and the one we had at the start. You would in fact be right, there is no difference between the two. Our animation still runs at 30 FPS. This is where flipping meshes comes into play."}),"\n",(0,i.jsxs)(n.p,{children:["Open ",(0,i.jsx)(n.code,{children:"level.lua"})," and replace"]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'pewpew.customizable_entity_set_mesh(id, "/dynamic/graphics.lua", mesh_index)\n'})}),"\n",(0,i.jsx)(n.p,{children:"with"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'pewpew.customizable_entity_set_flipping_meshes(id, "/dynamic/graphics.lua", mesh_index, mesh_index + 1)\n'})}),"\n",(0,i.jsxs)(n.p,{children:["What does this exactly do? When we set flipping meshes of an entity, that entity goes over the two specified meshes in a single game tick. This means that, in the first game tick, it will have the mesh at ",(0,i.jsx)(n.code,{children:"index 0"})," for half a tick and will have the mesh at ",(0,i.jsx)(n.code,{children:"index 1"})," for the rest half of a tick. In the next tick, we are resetting the flipping meshes. The variable ",(0,i.jsx)(n.code,{children:"mesh_index"})," now has a value of ",(0,i.jsx)(n.code,{children:"2"}),". The entity now has the mesh at ",(0,i.jsx)(n.code,{children:"index 2"})," for half a tick and has the mesh at ",(0,i.jsx)(n.code,{children:"index 3"})," for half a tick. Notice that we have gone over 4 meshes in just 2 game ticks (2 meshes per game tick)! The way in which we have used this creates an animation that runs at 60 FPS. Now, if you ",(0,i.jsx)(n.strong,{children:"save the files and run your level"}),", you'll notice that it is a lot smoother than our initial animation. It is exactly twice as smooth. It might look something like this:"]}),"\n",(0,i.jsx)(o(),{controls:!0,playing:!0,loop:!0,url:"https://github.com/pewpewlive/ppl-utils/assets/42890752/342de310-cc7b-4b4b-8c35-5cf34d078ad0"}),"\n",(0,i.jsx)(n.p,{children:"Congratulations! You have successfully made an animation that runs at 60 frames per second. I hope that you were able to understand this fairly well. Now, experiment with your code and make creative animations."})]})}function u(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(m,{...e})}):m(e)}}}]); \ No newline at end of file diff --git a/assets/js/0e384e19.0e880dff.js b/assets/js/0e384e19.0e880dff.js new file mode 100644 index 0000000..b129afb --- /dev/null +++ b/assets/js/0e384e19.0e880dff.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[3976],{1512:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>r,toc:()=>d});var n=t(4848),s=t(8453);const l={sidebar_position:1},o="Introduction",r={id:"intro",title:"Introduction",description:"This community-maintained wiki holds the resources useful for creating custom levels for PewPew Live.",source:"@site/docs/intro.md",sourceDirName:".",slug:"/intro",permalink:"/ppl-docs/docs/intro",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/intro.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Types",permalink:"/ppl-docs/docs/APIs/types"}},a={},d=[{value:"Level structure",id:"level-structure",level:2},{value:"Uploading your level",id:"uploading-your-level",level:2},{value:"Recommended Lua Style guide",id:"recommended-lua-style-guide",level:2},{value:"Helpful tools and utilities",id:"helpful-tools-and-utilities",level:2}];function c(e){const i={a:"a",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.h1,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsx)(i.p,{children:"This community-maintained wiki holds the resources useful for creating custom levels for PewPew Live."}),"\n",(0,n.jsxs)(i.p,{children:["Levels are created by writing Lua code. If you are new to programming or new to Lua, a good first step is to start with the ",(0,n.jsx)(i.a,{href:"Guides/Lua/beginner",children:"Beginner"})," guide."]}),"\n",(0,n.jsxs)(i.p,{children:["If you are already familiar with programming, a good approach is to first look at the examples (for example, the ",(0,n.jsx)(i.a,{href:"https://github.com/jyaif/ppl-utils/blob/d32dbec8a171c9bcc0f800dcd864f175c42c34fd/content/levels/simple_level/",children:"simple_level"}),") to get a feeling of how a level is made, and then come back to the wiki to get more precise information about the various aspect of level creation."]}),"\n",(0,n.jsxs)(i.p,{children:["If you have questions, the game's creator and many level creators are available on ",(0,n.jsx)(i.a,{href:"https://pewpew.live/discord",children:"Discord"}),"."]}),"\n",(0,n.jsx)(i.h2,{id:"level-structure",children:"Level structure"}),"\n",(0,n.jsxs)(i.p,{children:["A level is a directory that contains a ",(0,n.jsx)(i.a,{href:"File%20Information/manifest-files",children:"manifest"})," and Lua files. The Lua files fall in three categories:"]}),"\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsxs)(i.li,{children:["Files that describe ",(0,n.jsx)(i.a,{href:"File%20Information/mesh-files",children:"graphics"}),"."]}),"\n",(0,n.jsxs)(i.li,{children:["Files that describe ",(0,n.jsx)(i.a,{href:"File%20Information/sound-files",children:"sounds"}),"."]}),"\n",(0,n.jsxs)(i.li,{children:["Files that describe the behavior of the level. They make use of the ",(0,n.jsx)(i.a,{href:"APIs/PewPew",children:"pewpew"})," and ",(0,n.jsx)(i.a,{href:"APIs/Fmath",children:"fmath"})," libraries, which require an understanding of the ",(0,n.jsx)(i.a,{href:"APIs/types",children:"types"})," used."]}),"\n"]}),"\n",(0,n.jsx)(i.h2,{id:"uploading-your-level",children:"Uploading your level"}),"\n",(0,n.jsxs)(i.p,{children:["You can upload your level by signing into your account on ",(0,n.jsx)(i.a,{href:"https://pewpew.live",children:"https://pewpew.live"})," and navigating to the ",(0,n.jsx)(i.em,{children:"Manage your custom levels"})," page."]}),"\n",(0,n.jsx)(i.h2,{id:"recommended-lua-style-guide",children:"Recommended Lua Style guide"}),"\n",(0,n.jsxs)(i.p,{children:["When writing code, it is recommended to follow ",(0,n.jsx)(i.a,{href:"https://github.com/luarocks/lua-style-guide",children:"LuaRocks's style guide"}),", but using 2 space\nindentation to be consistent with the rest of PewPew's codebase."]}),"\n",(0,n.jsx)(i.h2,{id:"helpful-tools-and-utilities",children:"Helpful tools and utilities"}),"\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.a,{href:"https://hybroid.pewpew.live/pps/",children:"PewPew Snippets"})," is an essential Visual Studio Code extension that offers autocompletion and useful code snippets for creating levels."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.a,{href:"https://github.com/ModEngineer/PewPewLive-MeshExporter",children:"PewPewLive-MeshExporter"})," is a Blender plugin for converting scenes into PewPew Live 3D meshes."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.a,{href:"https://github.com/glebi574/PPLAF/",children:"PPLAF"})," is an opinionated Lua framework for creating advanced levels."]}),"\n"]})]})}function h(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,n.jsx)(i,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},8453:(e,i,t)=>{t.d(i,{R:()=>o,x:()=>r});var n=t(6540);const s={},l=n.createContext(s);function o(e){const i=n.useContext(l);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function r(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(l.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0e384e19.e32aa872.js b/assets/js/0e384e19.e32aa872.js deleted file mode 100644 index dafde3d..0000000 --- a/assets/js/0e384e19.e32aa872.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[3976],{1512:(e,i,t)=>{t.r(i),t.d(i,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>r,toc:()=>d});var n=t(4848),s=t(8453);const l={sidebar_position:1},o="Introduction",r={id:"intro",title:"Introduction",description:"This community-maintained wiki holds the resources useful for creating custom levels for PewPew Live.",source:"@site/docs/intro.md",sourceDirName:".",slug:"/intro",permalink:"/docs/intro",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/intro.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",next:{title:"Types",permalink:"/docs/APIs/types"}},a={},d=[{value:"Level structure",id:"level-structure",level:2},{value:"Uploading your level",id:"uploading-your-level",level:2},{value:"Recommended Lua Style guide",id:"recommended-lua-style-guide",level:2},{value:"Helpful tools and utilities",id:"helpful-tools-and-utilities",level:2}];function c(e){const i={a:"a",em:"em",h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,s.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(i.h1,{id:"introduction",children:"Introduction"}),"\n",(0,n.jsx)(i.p,{children:"This community-maintained wiki holds the resources useful for creating custom levels for PewPew Live."}),"\n",(0,n.jsxs)(i.p,{children:["Levels are created by writing Lua code. If you are new to programming or new to Lua, a good first step is to start with the ",(0,n.jsx)(i.a,{href:"Guides/Lua/beginner",children:"Beginner"})," guide."]}),"\n",(0,n.jsxs)(i.p,{children:["If you are already familiar with programming, a good approach is to first look at the examples (for example, the ",(0,n.jsx)(i.a,{href:"https://github.com/jyaif/ppl-utils/blob/d32dbec8a171c9bcc0f800dcd864f175c42c34fd/content/levels/simple_level/",children:"simple_level"}),") to get a feeling of how a level is made, and then come back to the wiki to get more precise information about the various aspect of level creation."]}),"\n",(0,n.jsxs)(i.p,{children:["If you have questions, the game's creator and many level creators are available on ",(0,n.jsx)(i.a,{href:"https://pewpew.live/discord",children:"Discord"}),"."]}),"\n",(0,n.jsx)(i.h2,{id:"level-structure",children:"Level structure"}),"\n",(0,n.jsxs)(i.p,{children:["A level is a directory that contains a ",(0,n.jsx)(i.a,{href:"File%20Information/manifest-files",children:"manifest"})," and Lua files. The Lua files fall in three categories:"]}),"\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsxs)(i.li,{children:["Files that describe ",(0,n.jsx)(i.a,{href:"File%20Information/mesh-files",children:"graphics"}),"."]}),"\n",(0,n.jsxs)(i.li,{children:["Files that describe ",(0,n.jsx)(i.a,{href:"File%20Information/sound-files",children:"sounds"}),"."]}),"\n",(0,n.jsxs)(i.li,{children:["Files that describe the behavior of the level. They make use of the ",(0,n.jsx)(i.a,{href:"APIs/PewPew",children:"pewpew"})," and ",(0,n.jsx)(i.a,{href:"APIs/Fmath",children:"fmath"})," libraries, which require an understanding of the ",(0,n.jsx)(i.a,{href:"APIs/types",children:"types"})," used."]}),"\n"]}),"\n",(0,n.jsx)(i.h2,{id:"uploading-your-level",children:"Uploading your level"}),"\n",(0,n.jsxs)(i.p,{children:["You can upload your level by signing into your account on ",(0,n.jsx)(i.a,{href:"https://pewpew.live",children:"https://pewpew.live"})," and navigating to the ",(0,n.jsx)(i.em,{children:"Manage your custom levels"})," page."]}),"\n",(0,n.jsx)(i.h2,{id:"recommended-lua-style-guide",children:"Recommended Lua Style guide"}),"\n",(0,n.jsxs)(i.p,{children:["When writing code, it is recommended to follow ",(0,n.jsx)(i.a,{href:"https://github.com/luarocks/lua-style-guide",children:"LuaRocks's style guide"}),", but using 2 space\nindentation to be consistent with the rest of PewPew's codebase."]}),"\n",(0,n.jsx)(i.h2,{id:"helpful-tools-and-utilities",children:"Helpful tools and utilities"}),"\n",(0,n.jsxs)(i.ul,{children:["\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.a,{href:"https://hybroid.pewpew.live/pps/",children:"PewPew Snippets"})," is an essential Visual Studio Code extension that offers autocompletion and useful code snippets for creating levels."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.a,{href:"https://github.com/ModEngineer/PewPewLive-MeshExporter",children:"PewPewLive-MeshExporter"})," is a Blender plugin for converting scenes into PewPew Live 3D meshes."]}),"\n",(0,n.jsxs)(i.li,{children:[(0,n.jsx)(i.a,{href:"https://github.com/glebi574/PPLAF/",children:"PPLAF"})," is an opinionated Lua framework for creating advanced levels."]}),"\n"]})]})}function h(e={}){const{wrapper:i}={...(0,s.R)(),...e.components};return i?(0,n.jsx)(i,{...e,children:(0,n.jsx)(c,{...e})}):c(e)}},8453:(e,i,t)=>{t.d(i,{R:()=>o,x:()=>r});var n=t(6540);const s={},l=n.createContext(s);function o(e){const i=n.useContext(l);return n.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function r(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),n.createElement(l.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0f881721.d2a951bb.js b/assets/js/0f881721.d2a951bb.js new file mode 100644 index 0000000..f6f486c --- /dev/null +++ b/assets/js/0f881721.d2a951bb.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[7810],{1580:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var n=t(4848),i=t(8453);const s={sidebar_position:3},o="Trivia",a={id:"other/trivia",title:"Trivia",description:"This page contains a random bag of technical information concerning PewPew Live.",source:"@site/docs/other/trivia.md",sourceDirName:"other",slug:"/other/trivia",permalink:"/ppl-docs/docs/other/trivia",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/other/trivia.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Level restrictions",permalink:"/ppl-docs/docs/other/level-restrictions"}},l={},c=[{value:"The Lua interpreter",id:"the-lua-interpreter",level:2},{value:"Version number",id:"version-number",level:2},{value:"Ports",id:"ports",level:2}];function p(e){const r={h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.h1,{id:"trivia",children:"Trivia"}),"\n",(0,n.jsx)(r.p,{children:"This page contains a random bag of technical information concerning PewPew Live."}),"\n",(0,n.jsx)(r.h2,{id:"the-lua-interpreter",children:"The Lua interpreter"}),"\n",(0,n.jsx)(r.p,{children:"PewPew Live uses a fork of Lua 5.3."}),"\n",(0,n.jsx)(r.h2,{id:"version-number",children:"Version number"}),"\n",(0,n.jsx)(r.p,{children:"PewPew Live's version numbers consist of 3 parts: MAJOR.MINOR.BUILD"}),"\n",(0,n.jsx)(r.p,{children:"MAJOR and MINOR may get updated with any significant release.\nThe BUILD number is an ever-increasing number representing a point in time of PewPew Live's development."}),"\n",(0,n.jsx)(r.h2,{id:"ports",children:"Ports"}),"\n",(0,n.jsx)(r.p,{children:"PewPew Live uses several different ports."}),"\n",(0,n.jsxs)(r.ul,{children:["\n",(0,n.jsx)(r.li,{children:"Multiplayer servers open the 51980 UDP port. If the port is unavailable, the server will try all ports up to 51989. If they are all taken, it will try to open ports random ports in the 49152-65535 range."}),"\n",(0,n.jsx)(r.li,{children:"LAN multiplayer room discovery is made by broadcasting on the ports 19869, 23902, 28013, 40124, 58240."}),"\n",(0,n.jsx)(r.li,{children:"The custom level development server exposes an http server on the TCP port 9000."}),"\n"]})]})}function d(e={}){const{wrapper:r}={...(0,i.R)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},8453:(e,r,t)=>{t.d(r,{R:()=>o,x:()=>a});var n=t(6540);const i={},s=n.createContext(i);function o(e){const r=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),n.createElement(s.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/0f881721.f8e95083.js b/assets/js/0f881721.f8e95083.js deleted file mode 100644 index a3cda83..0000000 --- a/assets/js/0f881721.f8e95083.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[7810],{1580:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>o,default:()=>d,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var n=t(4848),i=t(8453);const s={sidebar_position:3},o="Trivia",a={id:"other/trivia",title:"Trivia",description:"This page contains a random bag of technical information concerning PewPew Live.",source:"@site/docs/other/trivia.md",sourceDirName:"other",slug:"/other/trivia",permalink:"/docs/other/trivia",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/other/trivia.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Level restrictions",permalink:"/docs/other/level-restrictions"}},l={},c=[{value:"The Lua interpreter",id:"the-lua-interpreter",level:2},{value:"Version number",id:"version-number",level:2},{value:"Ports",id:"ports",level:2}];function p(e){const r={h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,i.R)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.h1,{id:"trivia",children:"Trivia"}),"\n",(0,n.jsx)(r.p,{children:"This page contains a random bag of technical information concerning PewPew Live."}),"\n",(0,n.jsx)(r.h2,{id:"the-lua-interpreter",children:"The Lua interpreter"}),"\n",(0,n.jsx)(r.p,{children:"PewPew Live uses a fork of Lua 5.3."}),"\n",(0,n.jsx)(r.h2,{id:"version-number",children:"Version number"}),"\n",(0,n.jsx)(r.p,{children:"PewPew Live's version numbers consist of 3 parts: MAJOR.MINOR.BUILD"}),"\n",(0,n.jsx)(r.p,{children:"MAJOR and MINOR may get updated with any significant release.\nThe BUILD number is an ever-increasing number representing a point in time of PewPew Live's development."}),"\n",(0,n.jsx)(r.h2,{id:"ports",children:"Ports"}),"\n",(0,n.jsx)(r.p,{children:"PewPew Live uses several different ports."}),"\n",(0,n.jsxs)(r.ul,{children:["\n",(0,n.jsx)(r.li,{children:"Multiplayer servers open the 51980 UDP port. If the port is unavailable, the server will try all ports up to 51989. If they are all taken, it will try to open ports random ports in the 49152-65535 range."}),"\n",(0,n.jsx)(r.li,{children:"LAN multiplayer room discovery is made by broadcasting on the ports 19869, 23902, 28013, 40124, 58240."}),"\n",(0,n.jsx)(r.li,{children:"The custom level development server exposes an http server on the TCP port 9000."}),"\n"]})]})}function d(e={}){const{wrapper:r}={...(0,i.R)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},8453:(e,r,t)=>{t.d(r,{R:()=>o,x:()=>a});var n=t(6540);const i={},s=n.createContext(i);function o(e){const r=n.useContext(s);return n.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function a(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),n.createElement(s.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/12193896.5b738686.js b/assets/js/12193896.5b738686.js new file mode 100644 index 0000000..08406ab --- /dev/null +++ b/assets/js/12193896.5b738686.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[5088],{6592:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>a,contentTitle:()=>t,default:()=>p,frontMatter:()=>l,metadata:()=>o,toc:()=>d});var s=n(4848),r=n(8453);const l={sidebar_position:1},t="Design principles",o={id:"other/level-design-principles",title:"Design principles",description:"General guidelines",source:"@site/docs/other/level-design-principles.md",sourceDirName:"other",slug:"/other/level-design-principles",permalink:"/ppl-docs/docs/other/level-design-principles",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/other/level-design-principles.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"60 FPS Animation",permalink:"/ppl-docs/docs/Guides/Other/fps-animation"},next:{title:"Level restrictions",permalink:"/ppl-docs/docs/other/level-restrictions"}},a={},d=[{value:"General guidelines",id:"general-guidelines",level:2},{value:"Gameplay advice",id:"gameplay-advice",level:2},{value:"Users will try to camp in the corners",id:"users-will-try-to-camp-in-the-corners",level:3},{value:"Fair randomness",id:"fair-randomness",level:3},{value:"Be mindful of farming",id:"be-mindful-of-farming",level:3}];function c(e){const i={h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.h1,{id:"design-principles",children:"Design principles"}),"\n",(0,s.jsx)(i.h2,{id:"general-guidelines",children:"General guidelines"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"Gameplay is king."}),"\n",(0,s.jsx)(i.li,{children:"Prefer procedurally generated graphics over manually created graphics."}),"\n",(0,s.jsx)(i.li,{children:"Prefer angular designs instead of curved designs."}),"\n",(0,s.jsx)(i.li,{children:"Prefer abstract designs over realistic designs."}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"gameplay-advice",children:"Gameplay advice"}),"\n",(0,s.jsx)(i.h3,{id:"users-will-try-to-camp-in-the-corners",children:"Users will try to camp in the corners"}),"\n",(0,s.jsx)(i.p,{children:"Corners reduce the exposure of the players' ships, so players will naturally tend to hide there. Either incentivize players to move by putting bonuses away from the corners, or de-incentivize players from staying there by spawning enemies there.\nThe same thing applies (to a lesser extent) to level's borders."}),"\n",(0,s.jsx)(i.h3,{id:"fair-randomness",children:"Fair randomness"}),"\n",(0,s.jsx)(i.p,{children:"If players have a very slim chance of getting a bonus that massively increases their score, the top of the leaderboard will be populated by people that were lucky, not by people that were skilled. This is not necessarily a bad thing, but it's something to keep in mind."}),"\n",(0,s.jsx)(i.h3,{id:"be-mindful-of-farming",children:"Be mindful of farming"}),"\n",(0,s.jsx)(i.p,{children:"Ask yourself if it is possible for the player to accumulate a lot of points (or a lot of shields) simply by not triggering an event. For example, I once made a level where shields kept appearing until all enemies were killed. Some players discovered that by leaving one enemy alive, they could farm shields."})]})}function p(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},8453:(e,i,n)=>{n.d(i,{R:()=>t,x:()=>o});var s=n(6540);const r={},l=s.createContext(r);function t(e){const i=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function o(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:t(e.components),s.createElement(l.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/12193896.cf39a8ea.js b/assets/js/12193896.cf39a8ea.js deleted file mode 100644 index 7b27345..0000000 --- a/assets/js/12193896.cf39a8ea.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[5088],{6592:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>o,contentTitle:()=>t,default:()=>p,frontMatter:()=>l,metadata:()=>a,toc:()=>d});var s=n(4848),r=n(8453);const l={sidebar_position:1},t="Design principles",a={id:"other/level-design-principles",title:"Design principles",description:"General guidelines",source:"@site/docs/other/level-design-principles.md",sourceDirName:"other",slug:"/other/level-design-principles",permalink:"/docs/other/level-design-principles",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/other/level-design-principles.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"60 FPS Animation",permalink:"/docs/Guides/Other/fps-animation"},next:{title:"Level restrictions",permalink:"/docs/other/level-restrictions"}},o={},d=[{value:"General guidelines",id:"general-guidelines",level:2},{value:"Gameplay advice",id:"gameplay-advice",level:2},{value:"Users will try to camp in the corners",id:"users-will-try-to-camp-in-the-corners",level:3},{value:"Fair randomness",id:"fair-randomness",level:3},{value:"Be mindful of farming",id:"be-mindful-of-farming",level:3}];function c(e){const i={h1:"h1",h2:"h2",h3:"h3",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i.h1,{id:"design-principles",children:"Design principles"}),"\n",(0,s.jsx)(i.h2,{id:"general-guidelines",children:"General guidelines"}),"\n",(0,s.jsxs)(i.ul,{children:["\n",(0,s.jsx)(i.li,{children:"Gameplay is king."}),"\n",(0,s.jsx)(i.li,{children:"Prefer procedurally generated graphics over manually created graphics."}),"\n",(0,s.jsx)(i.li,{children:"Prefer angular designs instead of curved designs."}),"\n",(0,s.jsx)(i.li,{children:"Prefer abstract designs over realistic designs."}),"\n"]}),"\n",(0,s.jsx)(i.h2,{id:"gameplay-advice",children:"Gameplay advice"}),"\n",(0,s.jsx)(i.h3,{id:"users-will-try-to-camp-in-the-corners",children:"Users will try to camp in the corners"}),"\n",(0,s.jsx)(i.p,{children:"Corners reduce the exposure of the players' ships, so players will naturally tend to hide there. Either incentivize players to move by putting bonuses away from the corners, or de-incentivize players from staying there by spawning enemies there.\nThe same thing applies (to a lesser extent) to level's borders."}),"\n",(0,s.jsx)(i.h3,{id:"fair-randomness",children:"Fair randomness"}),"\n",(0,s.jsx)(i.p,{children:"If players have a very slim chance of getting a bonus that massively increases their score, the top of the leaderboard will be populated by people that were lucky, not by people that were skilled. This is not necessarily a bad thing, but it's something to keep in mind."}),"\n",(0,s.jsx)(i.h3,{id:"be-mindful-of-farming",children:"Be mindful of farming"}),"\n",(0,s.jsx)(i.p,{children:"Ask yourself if it is possible for the player to accumulate a lot of points (or a lot of shields) simply by not triggering an event. For example, I once made a level where shields kept appearing until all enemies were killed. Some players discovered that by leaving one enemy alive, they could farm shields."})]})}function p(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,s.jsx)(i,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},8453:(e,i,n)=>{n.d(i,{R:()=>t,x:()=>a});var s=n(6540);const r={},l=s.createContext(r);function t(e){const i=s.useContext(l);return s.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function a(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:t(e.components),s.createElement(l.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3164f9fb.281a5b03.js b/assets/js/3164f9fb.281a5b03.js new file mode 100644 index 0000000..c4d904e --- /dev/null +++ b/assets/js/3164f9fb.281a5b03.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[198],{8730:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>r,default:()=>c,frontMatter:()=>s,metadata:()=>l,toc:()=>h});var i=n(4848),o=n(8453);const s={sidebar_position:2},r="Intermediate",l={id:"Guides/Lua/intermediate",title:"Intermediate",description:"If you are here, you made it through the learning process of the Lua language! Keep in mind, this section assumes that you know basic Lua. If you need to freshen up, look back onto the Beginner tutorials!",source:"@site/docs/Guides/Lua/intermediate.md",sourceDirName:"Guides/Lua",slug:"/Guides/Lua/intermediate",permalink:"/ppl-docs/docs/Guides/Lua/intermediate",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/Guides/Lua/intermediate.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Beginner Lua Tutorial",permalink:"/ppl-docs/docs/Guides/Lua/beginner"},next:{title:"Advanced",permalink:"/ppl-docs/docs/Guides/Lua/advanced"}},a={},h=[{value:"GETTING STARTED",id:"getting-started",level:3},{value:"PEWPEW LIVE API - FUNCTIONS",id:"pewpew-live-api---functions",level:3},{value:"PEWPEW LIVE API - FMATH",id:"pewpew-live-api---fmath",level:3},{value:"PEWPEW LIVE API - ENUMS",id:"pewpew-live-api---enums",level:3},{value:"WHERE DOES THE LEVEL GO?",id:"where-does-the-level-go",level:3},{value:"OPEN YOUR LEVEL",id:"open-your-level",level:3},{value:"THE START OF A LEVEL",id:"the-start-of-a-level",level:3}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h3:"h3",hr:"hr",img:"img",p:"p",pre:"pre",strong:"strong",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"intermediate",children:"Intermediate"}),"\n",(0,i.jsx)(t.p,{children:"If you are here, you made it through the learning process of the Lua language! Keep in mind, this section assumes that you know basic Lua. If you need to freshen up, look back onto the Beginner tutorials!"}),"\n",(0,i.jsxs)(t.p,{children:["Here, we will learn ",(0,i.jsx)(t.strong,{children:"how to make a PewPew Live Custom Level"})]}),"\n",(0,i.jsx)(t.h3,{id:"getting-started",children:"GETTING STARTED"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:"So in order to begin making a level, you will need to visit a couple of links."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.a,{href:"https://github.com/jyaif/ppl-utils",children:"https://github.com/jyaif/ppl-utils"})," <--- This link right here will take you to the files you need to make your level! Scroll down to ",(0,i.jsx)(t.strong,{children:"Getting Started"})," and follow the directions!"]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.a,{href:"https://pewpewlive.github.io/ppl-utils/",children:"https://pewpewlive.github.io/ppl-utils/"})," <--- This link right here is the PewPew Live API. That means, many important functions and items that are needed to make your level are found on this site!"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Also, make sure you have a text editor to make your code in! If you need help with this, go to the discord and ask about it in #technical-discuss!"})}),"\n",(0,i.jsx)(t.h3,{id:"pewpew-live-api---functions",children:"PEWPEW LIVE API - FUNCTIONS"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:"Before we begin in our first steps to making a level, it is crucial to understand the PewPew Live API."}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Let's take a look..."})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/cudNZOp.png",alt:"PewPew Live API Functions"})}),"\n",(0,i.jsxs)(t.p,{children:["These are some of the functions that you will be using in PewPew Live! I suggest giving it a lookover, and try to see what it all means! Whenever you use a function in PewPew's library (API), you MUST put ",(0,i.jsx)(t.code,{children:"pewpew."})," infront of it!"]}),"\n",(0,i.jsxs)(t.p,{children:["So you see, ",(0,i.jsx)(t.code,{children:"print(String str)"})," would be typed in your code as ",(0,i.jsx)(t.code,{children:"pewpew.print(String str)"}),". The black boxes with green text (things like ",(0,i.jsx)(t.code,{children:"String"}),", ",(0,i.jsx)(t.code,{children:"Int"}),", etc) tell you what kind of data the function uses, and what type of function it is! Don't worry too much about the type of function, focus mainly on the data that the functions take in, like ",(0,i.jsx)(t.code,{children:"Int"})," and ",(0,i.jsx)(t.code,{children:"String"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"pewpew-live-api---fmath",children:"PEWPEW LIVE API - FMATH"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Another main part of the API is the Fmath library!"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/S3KoZf8.png",alt:"PewPew Live API Fmath"})}),"\n",(0,i.jsxs)(t.p,{children:["These are more functions in PewPew Live, but slightly different. To use these functions, you MUST put ",(0,i.jsx)(t.code,{children:"fmath."})," infront of it!"]}),"\n",(0,i.jsxs)(t.p,{children:["So ",(0,i.jsx)(t.code,{children:"sqrt(FixedPoint x)"})," would be typed in your code as ",(0,i.jsx)(t.code,{children:"fmath.sqrt(FixedPoint x)"}),". Now, what exactly is ",(0,i.jsx)(t.code,{children:"FixedPoint"}),"?"]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.code,{children:"FixedPoint"})," refers to a specific kind of ",(0,i.jsx)(t.strong,{children:"number"})," in PewPew levels. We just call them fixed point numbers. They are strange, but don't worry, you'll get the hang of them! You really only use fixed point numbers when dealing with location and size. But don't worry, fixed point numbers and normal numbers are the same!"]}),"\n",(0,i.jsxs)(t.p,{children:["...For the most part. See, you write a normal number as ",(0,i.jsx)(t.code,{children:"n"}),", and fixed point numbers are written as ",(0,i.jsx)(t.code,{children:"nfx"}),". Fixed point numbers are put in the code by putting ",(0,i.jsx)(t.code,{children:"fx"})," after your number! So you have numbers like ",(0,i.jsx)(t.code,{children:"1, 2, 3"}),". But in fixed point numbers, they would be ",(0,i.jsx)(t.code,{children:"1fx, 2fx, 3fx"}),". And so on!"]}),"\n",(0,i.jsxs)(t.p,{children:["Another main difference I should note is their decimals! It's a little strange, and I won't go into too much detail, but ",(0,i.jsx)(t.code,{children:"2.6fx"})," does not exist. The number ",(0,i.jsx)(t.code,{children:"2.5"})," is written as ",(0,i.jsx)(t.code,{children:"2.2048fx"}),". It's strange, I know! And there is a specific and good reason for this! But for now, don't worry too much about decimals. If you need to use a number that isn't a full number, stick with fractions! Like instead of writing ",(0,i.jsx)(t.code,{children:"2.2048fx"}),", write ",(0,i.jsx)(t.code,{children:"5fx/2fx"}),"! See? Much better! ",(0,i.jsx)(t.strong,{children:"Just remember that these fixed point numbers are mostly used for location and size!"})," In later examples we will see exactly how they are used!"]}),"\n",(0,i.jsx)(t.h3,{id:"pewpew-live-api---enums",children:"PEWPEW LIVE API - ENUMS"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"The last main part that I need to cover is the Enums section of the API"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/6iA5ayl.png",alt:"PewPew Live API Enums"})}),"\n",(0,i.jsxs)(t.p,{children:["So what is an ",(0,i.jsx)(t.code,{children:"Enum"}),"? ",(0,i.jsx)(t.code,{children:"Enum"})," stands for ",(0,i.jsx)(t.em,{children:"Enumerator"}),", and is just a fancy way of talking about a list of items and properties. So here is the list of enemies and the properties of enemies, AKA the ",(0,i.jsx)(t.code,{children:"Enums"}),", that a person can access and use. Again, you need to put ",(0,i.jsx)(t.code,{children:"pewpew."})," infront of these when you use them. A quick example of a reference to a specific enemy would be ",(0,i.jsx)(t.code,{children:"pewpew.MothershipType.THREE_CORNERS"}),". This piece of code references the pink triangles (motherships) that you see in Eskiv."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"We will go into detail on how to use Enums in specific ways, but for now, that is the general briefing on how to read the PewPew Live API!"})}),"\n",(0,i.jsx)(t.h3,{id:"where-does-the-level-go",children:"WHERE DOES THE LEVEL GO?"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"So we are finally about to make our level. Where do we keep it? Well at the very top, you went to the main github page and downloaded the files, you need that!"})}),"\n",(0,i.jsxs)(t.p,{children:["You will need to extract the file, and then you will enter it. You will see two files, a folder and an ",(0,i.jsx)(t.code,{children:".exe"})," file. That ",(0,i.jsx)(t.code,{children:".exe"})," is very important to running your level, keep it in mind!"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/CrvXuXT.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsxs)(t.strong,{children:["You will then see a bunch of files, and a folder. You do NOT need to worry about these files at all! Just the folder! The ",(0,i.jsx)(t.code,{children:"levels"})," folder is where all custom levels are stored! So that is the folder you enter into next!"]})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/JVRk9P6.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"As you can see below, there are some levels already here! The developer, JF, put these levels here as examples for level creators to look at while they work! This is where you will create your level."})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/mgmeZ0g.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"So all you need to do is make a new folder. I'm going to call my folder TUTORIAL_LEVEL, although you can call your folder whatever you like."})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/OoUkG9m.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:"And there you go! You now have the location of your custom level, and all the levels are nice and organized! Time for the fun stuff!"}),"\n",(0,i.jsx)(t.h3,{id:"open-your-level",children:"OPEN YOUR LEVEL"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Here we can go into the environment that we need to code! Just to let you know, I use a text editor called Visual Studio Code. You may use something different, and again, if you need help with this text editor stuff, reach out in the discord!"})}),"\n",(0,i.jsx)(t.p,{children:"You can either open up just your level file in your text editor, or you can open the folder that contains all the levels. This is helpful for looking at other levels while you code! So head back to this screen below:"}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/JVRk9P6.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:"And open the levels folder with your text editor! If you need help with this, feel free to reach out for help! If you're ready, then proceed down below!"}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/BfYNE64.png",alt:""})}),"\n",(0,i.jsxs)(t.p,{children:["As pointed out by the very helpful green arrow, my level is on the left. The folder was initially empty. You need create a new script that will be your main level script. It HAS to be called ",(0,i.jsx)(t.code,{children:"level.lua"}),". This is how PewPew Live enters into your level and runs it. It might change in the future, but it is good practice to keep consistency. And with the script made, you have an empty canvas. What's next?"]}),"\n",(0,i.jsx)(t.h3,{id:"the-start-of-a-level",children:"THE START OF A LEVEL"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"This next portion will go over how to make your map, and how to spawn the player. Yes! You have to put in the code that spawns the player yourself! But don't worry, it's not too terrible."})}),"\n",(0,i.jsxs)(t.p,{children:["Look back into the PewPew API, there is a function that sets the map size. I'll state it here, it is ",(0,i.jsx)(t.code,{children:"set_level_size(FixedPoint width, FixedPoint height)"}),". This is the code that will make your map! It is very simple, and here is a sample code."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-lua",children:"local level_height = 300fx\nlocal level_length = 400fx\npewpew.set_level_size(level_length, level_height)\n"})}),"\n",(0,i.jsxs)(t.p,{children:["And that's all there is to it! You have made a map! Remember, when using a PewPew function, you MUST put ",(0,i.jsx)(t.code,{children:"pewpew."})," in front, or it won't work! And we are dealing with location/size, so fixed point numbers must be used! And you don't need to set the sizes as variables, I just consider it good practice. It's also easier to reference the map sizes if they are variables. You could have written ",(0,i.jsx)(t.code,{children:"pewpew.set_level_size(300fx, 400fx)"}),", but it's up to you."]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Hold it!"})," Before you try out your level, you need to spawn the player! This requires another handy function from the API. This one is ",(0,i.jsx)(t.code,{children:"new_player_ship(FixedPoint x, FixedPoint y, int player_index)"}),". A player's spawn point is a matter of ",(0,i.jsx)(t.em,{children:"location"}),", so fixed points are required! ",(0,i.jsx)(t.strong,{children:"Also, notice how the index is not a fixed point number, but a normal number!"})," The index is not size or location, so using normal numbers is fine!"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-lua",children:"pewpew.new_player_ship(100fx, 100fx, 0)\n"})}),"\n",(0,i.jsxs)(t.p,{children:["And there you have it! The player has spawned, and you have a map made. I should back track, what is ",(0,i.jsx)(t.code,{children:"player_index"}),"? And what does the ",(0,i.jsx)(t.code,{children:"0"}),' have to do with it? Well each player, whether it is single-player or multi-player, are assigned an "index" to keep track of which player is which. Player 1 has an index of ',(0,i.jsx)(t.code,{children:"0"}),", player 2 has an index ",(0,i.jsx)(t.code,{children:"1"}),", and so on. ",(0,i.jsx)(t.strong,{children:"BUT"})," at the current moment, custom levels only support one player, so whenever you use ",(0,i.jsx)(t.code,{children:"new_player_ship(FixedPoint x, FixedPoint y, int player_index)"}),", just use 0 for the ",(0,i.jsx)(t.code,{children:"player_index"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"The code above worked just fine, but another way, which is good practice, to write the above code is"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-lua",children:"local x_spawn = 100fx\nlocal y_spawn = 100fx\nlocal p1_index = 0\nlocal player1_ship = pewpew.new_player_ship(x_spawn, y_spawn, p1_index)\n"})}),"\n",(0,i.jsx)(t.p,{children:"This piece of code sets the ship as a variable that you can reference later on! I highly recommend using this second piece of code rather than the first one!"}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"And there you have it! Down below is the final product."})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/VHV6s29.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsxs)(t.strong,{children:["Now there's one more step before we can test out our level! We need something called a ",(0,i.jsx)(t.code,{children:"manifest"})]})}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"manifest"})," is your level description, name, and entry! I will explain entry in a bit, but for now, here's how to make a manifest. This one is actually written in a language other than Lua. I won't explain it too much, I will just show you the code and you can make a ",(0,i.jsx)(t.code,{children:"manifest"}),". But first, make a new file in your level folder and call it ",(0,i.jsx)(t.code,{children:"manifest.json"}),". ",(0,i.jsxs)(t.strong,{children:["NOT ",(0,i.jsx)(t.code,{children:"manifest.lua"}),". Like I said, it's a different language!"]})]}),"\n",(0,i.jsx)(t.p,{children:"In the manifest you need to put this piece of code:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-json",children:'{\n "name": "LEVEL_NAME",\n "descriptions": ["LEVEL DESCRIPTION"],\n "entry_point": "level.lua"\n}\n'})}),"\n",(0,i.jsxs)(t.p,{children:["You can look at it and kind of get a sense of what's going on, but I will brief you on it. You put your level name where ",(0,i.jsx)(t.code,{children:'"LEVEL_NAME"'})," is ",(0,i.jsx)(t.strong,{children:"INSIDE"})," the quotation ",(0,i.jsx)(t.code,{children:'""'})," marks! You can do the same with the level description, inside the quotation marks and brackets ",(0,i.jsx)(t.code,{children:'[""]'}),"! See the ",(0,i.jsx)(t.code,{children:'"entry_point"'}),"? That's why we named the main script ",(0,i.jsx)(t.code,{children:"level.lua"}),". The game enters through that script and runs your level. And that is ",(0,i.jsx)(t.em,{children:"all"})," you need to know about this new file. Down below is the manifest for my tutorial level."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/eMCp8e5.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:"You are done! You can run your level!"}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsxs)(t.strong,{children:["Ready to take it out for a spin? Good! Remember that ",(0,i.jsx)(t.code,{children:".exe"})," I mentioned some time back? Yeah, we need that. Head back to the screen below."]})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/CrvXuXT.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:"You need to run the ppl-utils file. It will open a window, and your computer will warn you about this file. Go ahead and run the file anyway, and you will be able to try out your level! You should get something like below:"}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/0GVpONe.png",alt:""})}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Your levels are being run! Now you need to go to the website that the screen above is telling you!"})," The website to run your levels is ",(0,i.jsx)(t.a,{href:"http://localhost:9000/pewpew.html",children:"http://localhost:9000/pewpew.html"})]}),"\n",(0,i.jsx)(t.p,{children:"You should get a screen like this:"}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/Diaobu9.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"As you can see, the manifest dictated what name my level would show as."})}),"\n",(0,i.jsx)(t.p,{children:'My tutorial world is at the top of the page, called "Tutorial Level". As it should, as that is what I put in the manifest above. You will need to find your level in the list of levels. And there you go! Just go into your level and give it a whirl!'})]})}function c(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>l});var i=n(6540);const o={},s=i.createContext(o);function r(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3164f9fb.d0740bee.js b/assets/js/3164f9fb.d0740bee.js deleted file mode 100644 index 470a919..0000000 --- a/assets/js/3164f9fb.d0740bee.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[198],{8730:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>r,default:()=>c,frontMatter:()=>s,metadata:()=>l,toc:()=>h});var i=n(4848),o=n(8453);const s={sidebar_position:2},r="Intermediate",l={id:"Guides/Lua/intermediate",title:"Intermediate",description:"If you are here, you made it through the learning process of the Lua language! Keep in mind, this section assumes that you know basic Lua. If you need to freshen up, look back onto the Beginner tutorials!",source:"@site/docs/Guides/Lua/intermediate.md",sourceDirName:"Guides/Lua",slug:"/Guides/Lua/intermediate",permalink:"/docs/Guides/Lua/intermediate",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/Guides/Lua/intermediate.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Beginner Lua Tutorial",permalink:"/docs/Guides/Lua/beginner"},next:{title:"Advanced",permalink:"/docs/Guides/Lua/advanced"}},a={},h=[{value:"GETTING STARTED",id:"getting-started",level:3},{value:"PEWPEW LIVE API - FUNCTIONS",id:"pewpew-live-api---functions",level:3},{value:"PEWPEW LIVE API - FMATH",id:"pewpew-live-api---fmath",level:3},{value:"PEWPEW LIVE API - ENUMS",id:"pewpew-live-api---enums",level:3},{value:"WHERE DOES THE LEVEL GO?",id:"where-does-the-level-go",level:3},{value:"OPEN YOUR LEVEL",id:"open-your-level",level:3},{value:"THE START OF A LEVEL",id:"the-start-of-a-level",level:3}];function d(e){const t={a:"a",code:"code",em:"em",h1:"h1",h3:"h3",hr:"hr",img:"img",p:"p",pre:"pre",strong:"strong",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"intermediate",children:"Intermediate"}),"\n",(0,i.jsx)(t.p,{children:"If you are here, you made it through the learning process of the Lua language! Keep in mind, this section assumes that you know basic Lua. If you need to freshen up, look back onto the Beginner tutorials!"}),"\n",(0,i.jsxs)(t.p,{children:["Here, we will learn ",(0,i.jsx)(t.strong,{children:"how to make a PewPew Live Custom Level"})]}),"\n",(0,i.jsx)(t.h3,{id:"getting-started",children:"GETTING STARTED"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:"So in order to begin making a level, you will need to visit a couple of links."}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.a,{href:"https://github.com/jyaif/ppl-utils",children:"https://github.com/jyaif/ppl-utils"})," <--- This link right here will take you to the files you need to make your level! Scroll down to ",(0,i.jsx)(t.strong,{children:"Getting Started"})," and follow the directions!"]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.a,{href:"https://pewpewlive.github.io/ppl-utils/",children:"https://pewpewlive.github.io/ppl-utils/"})," <--- This link right here is the PewPew Live API. That means, many important functions and items that are needed to make your level are found on this site!"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Also, make sure you have a text editor to make your code in! If you need help with this, go to the discord and ask about it in #technical-discuss!"})}),"\n",(0,i.jsx)(t.h3,{id:"pewpew-live-api---functions",children:"PEWPEW LIVE API - FUNCTIONS"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:"Before we begin in our first steps to making a level, it is crucial to understand the PewPew Live API."}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Let's take a look..."})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/cudNZOp.png",alt:"PewPew Live API Functions"})}),"\n",(0,i.jsxs)(t.p,{children:["These are some of the functions that you will be using in PewPew Live! I suggest giving it a lookover, and try to see what it all means! Whenever you use a function in PewPew's library (API), you MUST put ",(0,i.jsx)(t.code,{children:"pewpew."})," infront of it!"]}),"\n",(0,i.jsxs)(t.p,{children:["So you see, ",(0,i.jsx)(t.code,{children:"print(String str)"})," would be typed in your code as ",(0,i.jsx)(t.code,{children:"pewpew.print(String str)"}),". The black boxes with green text (things like ",(0,i.jsx)(t.code,{children:"String"}),", ",(0,i.jsx)(t.code,{children:"Int"}),", etc) tell you what kind of data the function uses, and what type of function it is! Don't worry too much about the type of function, focus mainly on the data that the functions take in, like ",(0,i.jsx)(t.code,{children:"Int"})," and ",(0,i.jsx)(t.code,{children:"String"}),"."]}),"\n",(0,i.jsx)(t.h3,{id:"pewpew-live-api---fmath",children:"PEWPEW LIVE API - FMATH"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Another main part of the API is the Fmath library!"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/S3KoZf8.png",alt:"PewPew Live API Fmath"})}),"\n",(0,i.jsxs)(t.p,{children:["These are more functions in PewPew Live, but slightly different. To use these functions, you MUST put ",(0,i.jsx)(t.code,{children:"fmath."})," infront of it!"]}),"\n",(0,i.jsxs)(t.p,{children:["So ",(0,i.jsx)(t.code,{children:"sqrt(FixedPoint x)"})," would be typed in your code as ",(0,i.jsx)(t.code,{children:"fmath.sqrt(FixedPoint x)"}),". Now, what exactly is ",(0,i.jsx)(t.code,{children:"FixedPoint"}),"?"]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.code,{children:"FixedPoint"})," refers to a specific kind of ",(0,i.jsx)(t.strong,{children:"number"})," in PewPew levels. We just call them fixed point numbers. They are strange, but don't worry, you'll get the hang of them! You really only use fixed point numbers when dealing with location and size. But don't worry, fixed point numbers and normal numbers are the same!"]}),"\n",(0,i.jsxs)(t.p,{children:["...For the most part. See, you write a normal number as ",(0,i.jsx)(t.code,{children:"n"}),", and fixed point numbers are written as ",(0,i.jsx)(t.code,{children:"nfx"}),". Fixed point numbers are put in the code by putting ",(0,i.jsx)(t.code,{children:"fx"})," after your number! So you have numbers like ",(0,i.jsx)(t.code,{children:"1, 2, 3"}),". But in fixed point numbers, they would be ",(0,i.jsx)(t.code,{children:"1fx, 2fx, 3fx"}),". And so on!"]}),"\n",(0,i.jsxs)(t.p,{children:["Another main difference I should note is their decimals! It's a little strange, and I won't go into too much detail, but ",(0,i.jsx)(t.code,{children:"2.6fx"})," does not exist. The number ",(0,i.jsx)(t.code,{children:"2.5"})," is written as ",(0,i.jsx)(t.code,{children:"2.2048fx"}),". It's strange, I know! And there is a specific and good reason for this! But for now, don't worry too much about decimals. If you need to use a number that isn't a full number, stick with fractions! Like instead of writing ",(0,i.jsx)(t.code,{children:"2.2048fx"}),", write ",(0,i.jsx)(t.code,{children:"5fx/2fx"}),"! See? Much better! ",(0,i.jsx)(t.strong,{children:"Just remember that these fixed point numbers are mostly used for location and size!"})," In later examples we will see exactly how they are used!"]}),"\n",(0,i.jsx)(t.h3,{id:"pewpew-live-api---enums",children:"PEWPEW LIVE API - ENUMS"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"The last main part that I need to cover is the Enums section of the API"})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/6iA5ayl.png",alt:"PewPew Live API Enums"})}),"\n",(0,i.jsxs)(t.p,{children:["So what is an ",(0,i.jsx)(t.code,{children:"Enum"}),"? ",(0,i.jsx)(t.code,{children:"Enum"})," stands for ",(0,i.jsx)(t.em,{children:"Enumerator"}),", and is just a fancy way of talking about a list of items and properties. So here is the list of enemies and the properties of enemies, AKA the ",(0,i.jsx)(t.code,{children:"Enums"}),", that a person can access and use. Again, you need to put ",(0,i.jsx)(t.code,{children:"pewpew."})," infront of these when you use them. A quick example of a reference to a specific enemy would be ",(0,i.jsx)(t.code,{children:"pewpew.MothershipType.THREE_CORNERS"}),". This piece of code references the pink triangles (motherships) that you see in Eskiv."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"We will go into detail on how to use Enums in specific ways, but for now, that is the general briefing on how to read the PewPew Live API!"})}),"\n",(0,i.jsx)(t.h3,{id:"where-does-the-level-go",children:"WHERE DOES THE LEVEL GO?"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"So we are finally about to make our level. Where do we keep it? Well at the very top, you went to the main github page and downloaded the files, you need that!"})}),"\n",(0,i.jsxs)(t.p,{children:["You will need to extract the file, and then you will enter it. You will see two files, a folder and an ",(0,i.jsx)(t.code,{children:".exe"})," file. That ",(0,i.jsx)(t.code,{children:".exe"})," is very important to running your level, keep it in mind!"]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/CrvXuXT.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsxs)(t.strong,{children:["You will then see a bunch of files, and a folder. You do NOT need to worry about these files at all! Just the folder! The ",(0,i.jsx)(t.code,{children:"levels"})," folder is where all custom levels are stored! So that is the folder you enter into next!"]})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/JVRk9P6.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"As you can see below, there are some levels already here! The developer, JF, put these levels here as examples for level creators to look at while they work! This is where you will create your level."})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/mgmeZ0g.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"So all you need to do is make a new folder. I'm going to call my folder TUTORIAL_LEVEL, although you can call your folder whatever you like."})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/OoUkG9m.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:"And there you go! You now have the location of your custom level, and all the levels are nice and organized! Time for the fun stuff!"}),"\n",(0,i.jsx)(t.h3,{id:"open-your-level",children:"OPEN YOUR LEVEL"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"Here we can go into the environment that we need to code! Just to let you know, I use a text editor called Visual Studio Code. You may use something different, and again, if you need help with this text editor stuff, reach out in the discord!"})}),"\n",(0,i.jsx)(t.p,{children:"You can either open up just your level file in your text editor, or you can open the folder that contains all the levels. This is helpful for looking at other levels while you code! So head back to this screen below:"}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/JVRk9P6.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:"And open the levels folder with your text editor! If you need help with this, feel free to reach out for help! If you're ready, then proceed down below!"}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/BfYNE64.png",alt:""})}),"\n",(0,i.jsxs)(t.p,{children:["As pointed out by the very helpful green arrow, my level is on the left. The folder was initially empty. You need create a new script that will be your main level script. It HAS to be called ",(0,i.jsx)(t.code,{children:"level.lua"}),". This is how PewPew Live enters into your level and runs it. It might change in the future, but it is good practice to keep consistency. And with the script made, you have an empty canvas. What's next?"]}),"\n",(0,i.jsx)(t.h3,{id:"the-start-of-a-level",children:"THE START OF A LEVEL"}),"\n",(0,i.jsx)(t.hr,{}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"This next portion will go over how to make your map, and how to spawn the player. Yes! You have to put in the code that spawns the player yourself! But don't worry, it's not too terrible."})}),"\n",(0,i.jsxs)(t.p,{children:["Look back into the PewPew API, there is a function that sets the map size. I'll state it here, it is ",(0,i.jsx)(t.code,{children:"set_level_size(FixedPoint width, FixedPoint height)"}),". This is the code that will make your map! It is very simple, and here is a sample code."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-lua",children:"local level_height = 300fx\nlocal level_length = 400fx\npewpew.set_level_size(level_length, level_height)\n"})}),"\n",(0,i.jsxs)(t.p,{children:["And that's all there is to it! You have made a map! Remember, when using a PewPew function, you MUST put ",(0,i.jsx)(t.code,{children:"pewpew."})," in front, or it won't work! And we are dealing with location/size, so fixed point numbers must be used! And you don't need to set the sizes as variables, I just consider it good practice. It's also easier to reference the map sizes if they are variables. You could have written ",(0,i.jsx)(t.code,{children:"pewpew.set_level_size(300fx, 400fx)"}),", but it's up to you."]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Hold it!"})," Before you try out your level, you need to spawn the player! This requires another handy function from the API. This one is ",(0,i.jsx)(t.code,{children:"new_player_ship(FixedPoint x, FixedPoint y, int player_index)"}),". A player's spawn point is a matter of ",(0,i.jsx)(t.em,{children:"location"}),", so fixed points are required! ",(0,i.jsx)(t.strong,{children:"Also, notice how the index is not a fixed point number, but a normal number!"})," The index is not size or location, so using normal numbers is fine!"]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-lua",children:"pewpew.new_player_ship(100fx, 100fx, 0)\n"})}),"\n",(0,i.jsxs)(t.p,{children:["And there you have it! The player has spawned, and you have a map made. I should back track, what is ",(0,i.jsx)(t.code,{children:"player_index"}),"? And what does the ",(0,i.jsx)(t.code,{children:"0"}),' have to do with it? Well each player, whether it is single-player or multi-player, are assigned an "index" to keep track of which player is which. Player 1 has an index of ',(0,i.jsx)(t.code,{children:"0"}),", player 2 has an index ",(0,i.jsx)(t.code,{children:"1"}),", and so on. ",(0,i.jsx)(t.strong,{children:"BUT"})," at the current moment, custom levels only support one player, so whenever you use ",(0,i.jsx)(t.code,{children:"new_player_ship(FixedPoint x, FixedPoint y, int player_index)"}),", just use 0 for the ",(0,i.jsx)(t.code,{children:"player_index"}),"."]}),"\n",(0,i.jsx)(t.p,{children:"The code above worked just fine, but another way, which is good practice, to write the above code is"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-lua",children:"local x_spawn = 100fx\nlocal y_spawn = 100fx\nlocal p1_index = 0\nlocal player1_ship = pewpew.new_player_ship(x_spawn, y_spawn, p1_index)\n"})}),"\n",(0,i.jsx)(t.p,{children:"This piece of code sets the ship as a variable that you can reference later on! I highly recommend using this second piece of code rather than the first one!"}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"And there you have it! Down below is the final product."})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/VHV6s29.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsxs)(t.strong,{children:["Now there's one more step before we can test out our level! We need something called a ",(0,i.jsx)(t.code,{children:"manifest"})]})}),"\n",(0,i.jsxs)(t.p,{children:["The ",(0,i.jsx)(t.code,{children:"manifest"})," is your level description, name, and entry! I will explain entry in a bit, but for now, here's how to make a manifest. This one is actually written in a language other than Lua. I won't explain it too much, I will just show you the code and you can make a ",(0,i.jsx)(t.code,{children:"manifest"}),". But first, make a new file in your level folder and call it ",(0,i.jsx)(t.code,{children:"manifest.json"}),". ",(0,i.jsxs)(t.strong,{children:["NOT ",(0,i.jsx)(t.code,{children:"manifest.lua"}),". Like I said, it's a different language!"]})]}),"\n",(0,i.jsx)(t.p,{children:"In the manifest you need to put this piece of code:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-json",children:'{\n "name": "LEVEL_NAME",\n "descriptions": ["LEVEL DESCRIPTION"],\n "entry_point": "level.lua"\n}\n'})}),"\n",(0,i.jsxs)(t.p,{children:["You can look at it and kind of get a sense of what's going on, but I will brief you on it. You put your level name where ",(0,i.jsx)(t.code,{children:'"LEVEL_NAME"'})," is ",(0,i.jsx)(t.strong,{children:"INSIDE"})," the quotation ",(0,i.jsx)(t.code,{children:'""'})," marks! You can do the same with the level description, inside the quotation marks and brackets ",(0,i.jsx)(t.code,{children:'[""]'}),"! See the ",(0,i.jsx)(t.code,{children:'"entry_point"'}),"? That's why we named the main script ",(0,i.jsx)(t.code,{children:"level.lua"}),". The game enters through that script and runs your level. And that is ",(0,i.jsx)(t.em,{children:"all"})," you need to know about this new file. Down below is the manifest for my tutorial level."]}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/eMCp8e5.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:"You are done! You can run your level!"}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsxs)(t.strong,{children:["Ready to take it out for a spin? Good! Remember that ",(0,i.jsx)(t.code,{children:".exe"})," I mentioned some time back? Yeah, we need that. Head back to the screen below."]})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/CrvXuXT.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:"You need to run the ppl-utils file. It will open a window, and your computer will warn you about this file. Go ahead and run the file anyway, and you will be able to try out your level! You should get something like below:"}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/0GVpONe.png",alt:""})}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Your levels are being run! Now you need to go to the website that the screen above is telling you!"})," The website to run your levels is ",(0,i.jsx)(t.a,{href:"http://localhost:9000/pewpew.html",children:"http://localhost:9000/pewpew.html"})]}),"\n",(0,i.jsx)(t.p,{children:"You should get a screen like this:"}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.img,{src:"https://i.imgur.com/Diaobu9.png",alt:""})}),"\n",(0,i.jsx)(t.p,{children:(0,i.jsx)(t.strong,{children:"As you can see, the manifest dictated what name my level would show as."})}),"\n",(0,i.jsx)(t.p,{children:'My tutorial world is at the top of the page, called "Tutorial Level". As it should, as that is what I put in the manifest above. You will need to find your level in the list of levels. And there you go! Just go into your level and give it a whirl!'})]})}function c(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(d,{...e})}):d(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>l});var i=n(6540);const o={},s=i.createContext(o);function r(e){const t=i.useContext(s);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:r(e.components),i.createElement(s.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/3679e0b2.65ca3eef.js b/assets/js/3679e0b2.65ca3eef.js new file mode 100644 index 0000000..196900f --- /dev/null +++ b/assets/js/3679e0b2.65ca3eef.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[3151],{4988:(t,e,o)=>{o.r(e),o.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var n=o(4848),s=o(8453);const r={slug:"first-blog-post",title:"First Blog Post",authors:"tastykiwi",tags:["first"]},i=void 0,a={permalink:"/ppl-docs/blog/first-blog-post",source:"@site/blog/2024-03-20-first-blog-post.md",title:"First Blog Post",description:"Welcome to the first blog article! We are so excited to move the entirety of PPL level development documentation here. This platform allows us to make more interactive (via React components), good looking documentation and having powerful search!",date:"2024-03-20T00:00:00.000Z",formattedDate:"March 20, 2024",tags:[{label:"first",permalink:"/ppl-docs/blog/tags/first"}],readingTime:.245,hasTruncateMarker:!1,authors:[{name:"Dominykas M.",title:"PewPew Live developer and creator of PPL Docs",url:"https://tastykiwi.omg.lol/",imageURL:"https://github.com/Tasty-Kiwi.png",key:"tastykiwi"}],frontMatter:{slug:"first-blog-post",title:"First Blog Post",authors:"tastykiwi",tags:["first"]},unlisted:!1},l={authorsImageUrls:[void 0]},c=[];function p(t){const e={p:"p",...(0,s.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.p,{children:"Welcome to the first blog article! We are so excited to move the entirety of PPL level development documentation here. This platform allows us to make more interactive (via React components), good looking documentation and having powerful search!"}),"\n",(0,n.jsx)(e.p,{children:"I hope you'll like the new home for PewPew docs."}),"\n",(0,n.jsx)(e.p,{children:"Enjoy!"})]})}function m(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(p,{...t})}):p(t)}},8453:(t,e,o)=>{o.d(e,{R:()=>i,x:()=>a});var n=o(6540);const s={},r=n.createContext(s);function i(t){const e=n.useContext(r);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:i(t.components),n.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/3679e0b2.d36cab8d.js b/assets/js/3679e0b2.d36cab8d.js deleted file mode 100644 index 87f391c..0000000 --- a/assets/js/3679e0b2.d36cab8d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[3151],{4988:(t,e,o)=>{o.r(e),o.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var n=o(4848),s=o(8453);const r={slug:"first-blog-post",title:"First Blog Post",authors:"tastykiwi",tags:["first"]},i=void 0,a={permalink:"/blog/first-blog-post",source:"@site/blog/2024-03-20-first-blog-post.md",title:"First Blog Post",description:"Welcome to the first blog article! We are so excited to move the entirety of PPL level development documentation here. This platform allows us to make more interactive (via React components), good looking documentation and having powerful search!",date:"2024-03-20T00:00:00.000Z",formattedDate:"March 20, 2024",tags:[{label:"first",permalink:"/blog/tags/first"}],readingTime:.245,hasTruncateMarker:!1,authors:[{name:"Dominykas M.",title:"PewPew Live developer and creator of PPL Docs",url:"https://tastykiwi.omg.lol/",imageURL:"https://github.com/Tasty-Kiwi.png",key:"tastykiwi"}],frontMatter:{slug:"first-blog-post",title:"First Blog Post",authors:"tastykiwi",tags:["first"]},unlisted:!1},l={authorsImageUrls:[void 0]},c=[];function p(t){const e={p:"p",...(0,s.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.p,{children:"Welcome to the first blog article! We are so excited to move the entirety of PPL level development documentation here. This platform allows us to make more interactive (via React components), good looking documentation and having powerful search!"}),"\n",(0,n.jsx)(e.p,{children:"I hope you'll like the new home for PewPew docs."}),"\n",(0,n.jsx)(e.p,{children:"Enjoy!"})]})}function m(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(p,{...t})}):p(t)}},8453:(t,e,o)=>{o.d(e,{R:()=>i,x:()=>a});var n=o(6540);const s={},r=n.createContext(s);function i(t){const e=n.useContext(r);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:i(t.components),n.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/4315fc58.04756219.js b/assets/js/4315fc58.04756219.js new file mode 100644 index 0000000..b944370 --- /dev/null +++ b/assets/js/4315fc58.04756219.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[7376],{2804:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>l,metadata:()=>c,toc:()=>o});var t=i(4848),s=i(8453);const l={sidebar_position:2},d="pewpew library",c={id:"APIs/PewPew",title:"PewPew",description:"The pewpew library contains all the functions for configuring levels and managing entities.",source:"@site/docs/APIs/PewPew.md",sourceDirName:"APIs",slug:"/APIs/PewPew",permalink:"/ppl-docs/docs/APIs/PewPew",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/APIs/PewPew.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Types",permalink:"/ppl-docs/docs/APIs/types"},next:{title:"Fmath",permalink:"/ppl-docs/docs/APIs/Fmath"}},a={},o=[{value:"Enums",id:"enums",level:2},{value:"EntityType",id:"entitytype",level:3},{value:"MothershipType",id:"mothershiptype",level:3},{value:"CannonType",id:"cannontype",level:3},{value:"CannonFrequency",id:"cannonfrequency",level:3},{value:"BombType",id:"bombtype",level:3},{value:"BonusType",id:"bonustype",level:3},{value:"WeaponType",id:"weapontype",level:3},{value:"AsteroidSize",id:"asteroidsize",level:3},{value:"Functions",id:"functions",level:2},{value:"print()",id:"print",level:3},{value:"print_debug_info()",id:"print_debug_info",level:3},{value:"set_level_size()",id:"set_level_size",level:3},{value:"add_wall()",id:"add_wall",level:3},{value:"remove_wall()",id:"remove_wall",level:3},{value:"add_update_callback()",id:"add_update_callback",level:3},{value:"get_number_of_players()",id:"get_number_of_players",level:3},{value:"increase_score_of_player()",id:"increase_score_of_player",level:3},{value:"increase_score_streak_of_player()",id:"increase_score_streak_of_player",level:3},{value:"get_score_streak_level()",id:"get_score_streak_level",level:3},{value:"stop_game()",id:"stop_game",level:3},{value:"get_player_inputs()",id:"get_player_inputs",level:3},{value:"get_score_of_player()",id:"get_score_of_player",level:3},{value:"configure_player()",id:"configure_player",level:3},{value:"configure_player_hud()",id:"configure_player_hud",level:3},{value:"get_player_configuration()",id:"get_player_configuration",level:3},{value:"configure_player_ship_weapon()",id:"configure_player_ship_weapon",level:3},{value:"add_damage_to_player_ship()",id:"add_damage_to_player_ship",level:3},{value:"add_arrow_to_player_ship()",id:"add_arrow_to_player_ship",level:3},{value:"remove_arrow_from_player_ship()",id:"remove_arrow_from_player_ship",level:3},{value:"make_player_ship_transparent()",id:"make_player_ship_transparent",level:3},{value:"set_player_ship_speed()",id:"set_player_ship_speed",level:3},{value:"get_all_entities()",id:"get_all_entities",level:3},{value:"get_entities_colliding_with_disk()",id:"get_entities_colliding_with_disk",level:3},{value:"get_entity_count()",id:"get_entity_count",level:3},{value:"get_entity_type()",id:"get_entity_type",level:3},{value:"play_ambient_sound()",id:"play_ambient_sound",level:3},{value:"play_sound()",id:"play_sound",level:3},{value:"create_explosion()",id:"create_explosion",level:3},{value:"new_asteroid()",id:"new_asteroid",level:3},{value:"new_asteroid_with_size()",id:"new_asteroid_with_size",level:3},{value:"new_baf()",id:"new_baf",level:3},{value:"new_baf_red()",id:"new_baf_red",level:3},{value:"new_baf_blue()",id:"new_baf_blue",level:3},{value:"new_bomb()",id:"new_bomb",level:3},{value:"new_bonus()",id:"new_bonus",level:3},{value:"new_crowder()",id:"new_crowder",level:3},{value:"new_floating_message()",id:"new_floating_message",level:3},{value:"new_customizable_entity()",id:"new_customizable_entity",level:3},{value:"new_inertiac()",id:"new_inertiac",level:3},{value:"new_mothership()",id:"new_mothership",level:3},{value:"new_pointonium()",id:"new_pointonium",level:3},{value:"new_player_ship()",id:"new_player_ship",level:3},{value:"new_player_bullet()",id:"new_player_bullet",level:3},{value:"new_rolling_cube()",id:"new_rolling_cube",level:3},{value:"new_rolling_sphere()",id:"new_rolling_sphere",level:3},{value:"new_wary()",id:"new_wary",level:3},{value:"new_ufo()",id:"new_ufo",level:3},{value:"rolling_cube_set_enable_collisions_with_walls()",id:"rolling_cube_set_enable_collisions_with_walls",level:3},{value:"ufo_set_enable_collisions_with_walls()",id:"ufo_set_enable_collisions_with_walls",level:3},{value:"entity_get_position()",id:"entity_get_position",level:3},{value:"entity_get_is_alive()",id:"entity_get_is_alive",level:3},{value:"entity_get_is_started_to_be_destroyed()",id:"entity_get_is_started_to_be_destroyed",level:3},{value:"entity_set_position()",id:"entity_set_position",level:3},{value:"entity_set_radius()",id:"entity_set_radius",level:3},{value:"entity_set_update_callback()",id:"entity_set_update_callback",level:3},{value:"entity_destroy()",id:"entity_destroy",level:3},{value:"entity_react_to_weapon()",id:"entity_react_to_weapon",level:3},{value:"customizable_entity_set_position_interpolation()",id:"customizable_entity_set_position_interpolation",level:3},{value:"customizable_entity_set_mesh()",id:"customizable_entity_set_mesh",level:3},{value:"customizable_entity_set_flipping_meshes()",id:"customizable_entity_set_flipping_meshes",level:3},{value:"customizable_entity_set_mesh_color()",id:"customizable_entity_set_mesh_color",level:3},{value:"customizable_entity_set_string()",id:"customizable_entity_set_string",level:3},{value:"customizable_entity_set_mesh_xyz()",id:"customizable_entity_set_mesh_xyz",level:3},{value:"customizable_entity_set_mesh_z()",id:"customizable_entity_set_mesh_z",level:3},{value:"customizable_entity_set_mesh_scale()",id:"customizable_entity_set_mesh_scale",level:3},{value:"customizable_entity_set_mesh_xyz_scale()",id:"customizable_entity_set_mesh_xyz_scale",level:3},{value:"customizable_entity_set_mesh_angle()",id:"customizable_entity_set_mesh_angle",level:3},{value:"customizable_entity_skip_mesh_attributes_interpolation()",id:"customizable_entity_skip_mesh_attributes_interpolation",level:3},{value:"customizable_entity_configure_music_response()",id:"customizable_entity_configure_music_response",level:3},{value:"customizable_entity_add_rotation_to_mesh()",id:"customizable_entity_add_rotation_to_mesh",level:3},{value:"customizable_entity_set_visibility_radius()",id:"customizable_entity_set_visibility_radius",level:3},{value:"customizable_entity_configure_wall_collision()",id:"customizable_entity_configure_wall_collision",level:3},{value:"customizable_entity_set_player_collision_callback()",id:"customizable_entity_set_player_collision_callback",level:3},{value:"customizable_entity_set_weapon_collision_callback()",id:"customizable_entity_set_weapon_collision_callback",level:3},{value:"customizable_entity_start_spawning()",id:"customizable_entity_start_spawning",level:3},{value:"customizable_entity_start_exploding()",id:"customizable_entity_start_exploding",level:3}];function r(e){const n={blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"pewpew-library",children:"pewpew library"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"pewpew"})," library contains all the functions for configuring levels and managing entities."]}),"\n",(0,t.jsx)(n.h2,{id:"enums",children:"Enums"}),"\n",(0,t.jsx)(n.h3,{id:"entitytype",children:"EntityType"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"ASTEROID"}),"\n",(0,t.jsx)(n.li,{children:"BAF"}),"\n",(0,t.jsx)(n.li,{children:"INERTIAC"}),"\n",(0,t.jsx)(n.li,{children:"MOTHERSHIP"}),"\n",(0,t.jsx)(n.li,{children:"MOTHERSHIP_BULLET"}),"\n",(0,t.jsx)(n.li,{children:"ROLLING_CUBE"}),"\n",(0,t.jsx)(n.li,{children:"ROLLING_SPHERE"}),"\n",(0,t.jsx)(n.li,{children:"UFO"}),"\n",(0,t.jsx)(n.li,{children:"WARY"}),"\n",(0,t.jsx)(n.li,{children:"CROWDER"}),"\n",(0,t.jsx)(n.li,{children:"CUSTOMIZABLE_ENTITY"}),"\n",(0,t.jsx)(n.li,{children:"SHIP"}),"\n",(0,t.jsx)(n.li,{children:"BOMB"}),"\n",(0,t.jsx)(n.li,{children:"BAF_BLUE"}),"\n",(0,t.jsx)(n.li,{children:"BAF_RED"}),"\n",(0,t.jsx)(n.li,{children:"WARY_MISSILE"}),"\n",(0,t.jsx)(n.li,{children:"UFO_BULLET"}),"\n",(0,t.jsx)(n.li,{children:"PLAYER_BULLET"}),"\n",(0,t.jsx)(n.li,{children:"BOMB_EXPLOSION"}),"\n",(0,t.jsx)(n.li,{children:"PLAYER_EXPLOSION"}),"\n",(0,t.jsx)(n.li,{children:"BONUS"}),"\n",(0,t.jsx)(n.li,{children:"FLOATING_MESSAGE"}),"\n",(0,t.jsx)(n.li,{children:"POINTONIUM"}),"\n",(0,t.jsx)(n.li,{children:"BONUS_IMPLOSION"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"mothershiptype",children:"MothershipType"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"THREE_CORNERS"}),"\n",(0,t.jsx)(n.li,{children:"FOUR_CORNERS"}),"\n",(0,t.jsx)(n.li,{children:"FIVE_CORNERS"}),"\n",(0,t.jsx)(n.li,{children:"SIX_CORNERS"}),"\n",(0,t.jsx)(n.li,{children:"SEVEN_CORNERS"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"cannontype",children:"CannonType"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"SINGLE"}),"\n",(0,t.jsx)(n.li,{children:"TIC_TOC"}),"\n",(0,t.jsx)(n.li,{children:"DOUBLE"}),"\n",(0,t.jsx)(n.li,{children:"TRIPLE"}),"\n",(0,t.jsx)(n.li,{children:"FOUR_DIRECTIONS"}),"\n",(0,t.jsx)(n.li,{children:"DOUBLE_SWIPE"}),"\n",(0,t.jsx)(n.li,{children:"HEMISPHERE"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"cannonfrequency",children:"CannonFrequency"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"FREQ_30"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_15"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_10"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_7_5"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_6"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_5"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_3"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_2"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_1"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"bombtype",children:"BombType"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"FREEZE"}),"\n",(0,t.jsx)(n.li,{children:"REPULSIVE"}),"\n",(0,t.jsx)(n.li,{children:"ATOMIZE"}),"\n",(0,t.jsx)(n.li,{children:"SMALL_ATOMIZE"}),"\n",(0,t.jsx)(n.li,{children:"SMALL_FREEZE"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"bonustype",children:"BonusType"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"REINSTANTIATION"}),"\n",(0,t.jsx)(n.li,{children:"SHIELD"}),"\n",(0,t.jsx)(n.li,{children:"SPEED"}),"\n",(0,t.jsx)(n.li,{children:"WEAPON"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"weapontype",children:"WeaponType"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"BULLET"}),"\n",(0,t.jsx)(n.li,{children:"FREEZE_EXPLOSION"}),"\n",(0,t.jsx)(n.li,{children:"REPULSIVE_EXPLOSION"}),"\n",(0,t.jsx)(n.li,{children:"ATOMIZE_EXPLOSION"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"asteroidsize",children:"AsteroidSize"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"SMALL"}),"\n",(0,t.jsx)(n.li,{children:"MEDIUM"}),"\n",(0,t.jsx)(n.li,{children:"LARGE"}),"\n",(0,t.jsx)(n.li,{children:"VERY_LARGE"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"functions",children:"Functions"}),"\n",(0,t.jsx)(n.h3,{id:"print",children:(0,t.jsx)(n.code,{children:"print()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.print(str: string)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Prints ",(0,t.jsx)(n.code,{children:"str"})," in the console for debugging."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'local some_number = 42\npewpew.print("the value of some_number is: " .. some_number)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"print_debug_info",children:(0,t.jsx)(n.code,{children:"print_debug_info()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.print_debug_info()\n"})}),"\n",(0,t.jsx)(n.p,{children:"Prints debug info: the number of entities created and the amount of memory used by the script."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"pewpew.print_debug_info()\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"set_level_size",children:(0,t.jsx)(n.code,{children:"set_level_size()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.set_level_size(\n width: FixedPoint,\n height: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the level's size. Implicetely adds walls to make sure that entities can not go outside of the level's boundaries. ",(0,t.jsx)(n.code,{children:"width"})," and ",(0,t.jsx)(n.code,{children:"height"})," are clamped to the range ]0fx, 6000fx]. If this function is not called, the level size is (10fx, 10fx), which is uselessly small for most cases."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local width = 300fx\nlocal height = 200fx\npewpew.set_level_size(width, height)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"add_wall",children:(0,t.jsx)(n.code,{children:"add_wall()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.add_wall(\n start_x: FixedPoint,\n start_y: FixedPoint,\n end_x: FixedPoint,\n end_y: FixedPoint\n): int\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Adds a wall to the level from (",(0,t.jsx)(n.code,{children:"start_x"}),",",(0,t.jsx)(n.code,{children:"start_y"}),") to (",(0,t.jsx)(n.code,{children:"end_x"}),",",(0,t.jsx)(n.code,{children:"end_y"}),"), and returns its wall ID. A maximum of 200 walls can be added to a level."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"pewpew.add_wall(100fx, 100fx, 200fx, 200fx)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"remove_wall",children:(0,t.jsx)(n.code,{children:"remove_wall()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.remove_wall(wall_id: int)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Remove the wall with the given ",(0,t.jsx)(n.code,{children:"wall_id"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local wall_id = pewpew.add_wall(100fx, 100fx, 200fx, 200fx)\n-- Later, when the wall needs to be removed:\npewpew.remove_wall(wall_id)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"add_update_callback",children:(0,t.jsx)(n.code,{children:"add_update_callback()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.add_update_callback(update_callback: function)\n"})}),"\n",(0,t.jsx)(n.p,{children:"Adds a callback that will be updated at each game tick."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'local tick_count = 0\npewpew.add_update_callback(function()\n pewpew.print("this is tick " .. tick_count)\n tick_count = tick_count + 1\nend)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_number_of_players",children:(0,t.jsx)(n.code,{children:"get_number_of_players()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_number_of_players(): int\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns the number of players in the game."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"increase_score_of_player",children:(0,t.jsx)(n.code,{children:"increase_score_of_player()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.increase_score_of_player(\n player_index: int,\n delta: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Increases the score of the player at the specified ",(0,t.jsx)(n.code,{children:"player_index"})," by an amount of ",(0,t.jsx)(n.code,{children:"delta"}),". ",(0,t.jsx)(n.code,{children:"player_index"})," must in the range [0, get_number_of_players() - 1]. Note that ",(0,t.jsx)(n.code,{children:"delta"})," can be negative."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"increase_score_streak_of_player",children:(0,t.jsx)(n.code,{children:"increase_score_streak_of_player()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.increase_score_streak_of_player(\n player_index: int,\n delta: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Increases the score streak counter of the player at the specified ",(0,t.jsx)(n.code,{children:"player_index"})," by an amount of ",(0,t.jsx)(n.code,{children:"delta"}),". This counter is used to determine at which level of score streak the player is at. In turn, the score streak level is used to determine how much pointonium is given. Typically the score streak counter should be increased when an enemy is destroyed with the same score that the enemy provide. ",(0,t.jsx)(n.code,{children:"player_index"})," must in the range [0, get_number_of_players() - 1]. Note that ",(0,t.jsx)(n.code,{children:"delta"})," can be negative."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_score_streak_level",children:(0,t.jsx)(n.code,{children:"get_score_streak_level()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_score_streak_level(player_index: int): int\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns a number between 0 and 3. 0 is the lowest score streak (no pointonium is given), while 3 is the highest (3 pointoniums is usually given)"}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"stop_game",children:(0,t.jsx)(n.code,{children:"stop_game()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.stop_game()\n"})}),"\n",(0,t.jsx)(n.p,{children:"Ends the current game."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_player_inputs",children:(0,t.jsx)(n.code,{children:"get_player_inputs()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_player_inputs(player_index: int): FixedPoint, FixedPoint, FixedPoint, FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the inputs of the player at the specified ",(0,t.jsx)(n.code,{children:"index"}),". The return values are in order: the movement joystick's angle (between 0 and 2pi), the movement joystick's distance (between 0 and 1), the shoot joystick's angle (between 0 and 2pi), and the shoot joystick's distance (between 0 and 1)."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local move_angle, move_distance, shoot_angle, shoot_distance = pewpew.get_player_inputs(0)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_score_of_player",children:(0,t.jsx)(n.code,{children:"get_score_of_player()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_score_of_player(player_index: int): int\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the score of the player at the specified ",(0,t.jsx)(n.code,{children:"player_index"}),". ",(0,t.jsx)(n.code,{children:"player_index"})," must in the range [0, get_number_of_players() - 1]."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"configure_player",children:(0,t.jsx)(n.code,{children:"configure_player()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.configure_player(\n player_index: int,\n configuration: table {\n has_lost: bool,\n shield: int,\n camera_x_override: FixedPoint,\n camera_y_override: FixedPoint,\n camera_distance: FixedPoint,\n camera_rotation_x_axis: FixedPoint,\n move_joystick_color: int,\n shoot_joystick_color: int\n }\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Configures the player at the specified ",(0,t.jsx)(n.code,{children:"player_index"}),". ",(0,t.jsx)(n.code,{children:"player_index"})," must in the range [0, get_number_of_players() - 1]. A ",(0,t.jsx)(n.code,{children:"camera_distance"})," less than 0fx makes the camera move away from the ship. ",(0,t.jsx)(n.code,{children:"camera_rotation_x_axis"})," is in radian and rotates along the X axis.\nTo temporarily override the XY position of the camera, set ",(0,t.jsx)(n.strong,{children:"both"})," ",(0,t.jsx)(n.code,{children:"camera_x_override"})," and ",(0,t.jsx)(n.code,{children:"camera_y_override"}),"; this will make the camera be interpolated from wherever it was, to that new position."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"pewpew.configure_player(0, {shield = 3, camera_distance = 50fx, move_joystick_color = 0xffff00ff})\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"configure_player_hud",children:(0,t.jsx)(n.code,{children:"configure_player_hud()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.configure_player_hud(\n player_index: int,\n configuration: table {\n top_left_line: string\n }\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Configures the player's HUD.",(0,t.jsx)(n.code,{children:"player_index"})," must in the range [0, get_number_of_players() - 1]."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'pewpew.configure_player_hud(0, {top_left_line = "Hello World"})\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_player_configuration",children:(0,t.jsx)(n.code,{children:"get_player_configuration()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_player_configuration(player_index: int): table {\n shield: int,\n has_lost: bool\n }\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns a map containing the configuration of the player at the specified ",(0,t.jsx)(n.code,{children:"player_index"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local shield = pewpew.get_player_configuration(0).shield\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"configure_player_ship_weapon",children:(0,t.jsx)(n.code,{children:"configure_player_ship_weapon()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.configure_player_ship_weapon(\n ship_id: EntityId,\n configuration: table {\n frequency: int,\n cannon: int,\n duration: int\n }\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Configures the weapon of the ship identified with ",(0,t.jsx)(n.code,{children:"ship_id"})," using ",(0,t.jsx)(n.code,{children:"configuration"}),". ",(0,t.jsx)(n.code,{children:"frequency"})," determines the frequency of the shots. ",(0,t.jsx)(n.code,{children:"cannon"})," determines the type of cannon. ",(0,t.jsx)(n.code,{children:"duration"})," determines the number of game ticks during which the weapon will be available. Once the duration expires, the weapon reverts to its permanent configuration. If ",(0,t.jsx)(n.code,{children:"duration"})," is omitted, the weapon will be permanently set to this configuration. If ",(0,t.jsx)(n.code,{children:"frequency"})," or ",(0,t.jsx)(n.code,{children:"cannon"})," is omitted, the ship is configured to not have any weapon."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local weapon_config = {frequency = pewpew.CannonFrequency.FREQ_10, cannon = pewpew.CannonType.DOUBLE}\nlocal ship_id = player_helpers.new_player_ship(100fx, 200fx, 0)\npewpew.configure_player_ship_weapon(ship_id, weapon_config)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"add_damage_to_player_ship",children:(0,t.jsx)(n.code,{children:"add_damage_to_player_ship()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.add_damage_to_player_ship(\n ship_id: EntityId,\n damage: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Reduces the amount of shield of the player that owns the ship by ",(0,t.jsx)(n.code,{children:"damage"})," points. If the player receives damage while having 0 shields left, the player loses."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"add_arrow_to_player_ship",children:(0,t.jsx)(n.code,{children:"add_arrow_to_player_ship()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.add_arrow_to_player_ship(\n ship_id: EntityId,\n target_id: EntityId,\n color: int\n): int\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Adds an arrow to the ship identified with ",(0,t.jsx)(n.code,{children:"ship_id"})," pointing towards the entity identified with ",(0,t.jsx)(n.code,{children:"entity_id"}),", and returns the identifier of the arrow. ",(0,t.jsx)(n.code,{children:"color"})," specifies the arrow's color. The arrow is automatically removed when the target entity is destroyed."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"remove_arrow_from_player_ship",children:(0,t.jsx)(n.code,{children:"remove_arrow_from_player_ship()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.remove_arrow_from_player_ship(\n ship_id: EntityId,\n arrow_id: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Removes the arrow identified by ",(0,t.jsx)(n.code,{children:"arrow_id"})," from the ship identified by ",(0,t.jsx)(n.code,{children:"ship_id"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"make_player_ship_transparent",children:(0,t.jsx)(n.code,{children:"make_player_ship_transparent()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.make_player_ship_transparent(\n ship_id: EntityId,\n transparency_duration: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Makes the player ship transparent for ",(0,t.jsx)(n.code,{children:"transparency_duration"})," game ticks."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"set_player_ship_speed",children:(0,t.jsx)(n.code,{children:"set_player_ship_speed()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.set_player_ship_speed(\n ship_id: EntityId,\n factor: FixedPoint,\n offset: FixedPoint,\n duration: int\n): FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets and returns the ",(0,t.jsx)(n.strong,{children:"effective speed"})," of the specified player ship as a function of the ",(0,t.jsx)(n.strong,{children:"base speed"})," of the ship. By default, a player ship moves according to its base speed, which is 10 distance units per tick (in the future, different ships may have different base speeds).\nAssuming the base speed of the ship is S, the new effective speed will be ",(0,t.jsx)(n.code,{children:"(factor*S)+offset"}),". ",(0,t.jsx)(n.code,{children:"duration"})," is the number of ticks during which the effective speed will be applied. Afterwards, the ship's speed reverts to its base speed. If ",(0,t.jsx)(n.code,{children:"duration"})," is negative, the effective speed never reverts to the base speed."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_all_entities",children:(0,t.jsx)(n.code,{children:"get_all_entities()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_all_entities(): List\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the list of the entityIDs of all the entities currently in the level. This includes the various bullets and ",(0,t.jsx)(n.em,{children:"all"})," the custom entities."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'local entities = pewpew.get_all_entities()\npewpew.print("There are " .. #entities .. " entities in the level")\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_entities_colliding_with_disk",children:(0,t.jsx)(n.code,{children:"get_entities_colliding_with_disk()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_entities_colliding_with_disk(\n center_x: FixedPoint,\n center_y: FixedPoint,\n radius: FixedPoint\n): List\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns the list of collidable entities (which includes all enemies) that overlap with the given disk."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local entities = pewpew.get_entities_colliding_with_disk(100fx, 100fx, 30fx)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_entity_count",children:(0,t.jsx)(n.code,{children:"get_entity_count()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_entity_count(type: int): int\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the number of entities of type ",(0,t.jsx)(n.code,{children:"type"})," that are alive."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local number_of_bafs = pewpew.get_entity_count(pewpew.EntityType.BAF)\nlocal number_of_asteroids = pewpew.get_entity_count(pewpew.EntityType.ASTEROID)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_entity_type",children:(0,t.jsx)(n.code,{children:"get_entity_type()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_entity_type(entity_id: EntityId): int\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns the type of the given entity."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'local type = pewpew.get_entity_type(id)\nif type == pewpew.EntityType.BAF then\n pewpew.print("the entity is a BAF")\nend\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"play_ambient_sound",children:(0,t.jsx)(n.code,{children:"play_ambient_sound()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.play_ambient_sound(\n sound_path: string,\n index: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Plays the sound described at ",(0,t.jsx)(n.code,{children:"sound_path"})," at the index ",(0,t.jsx)(n.code,{children:"index"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'pewpew.play_ambient_sound("/dynamic/my_custom_sound.lua", 0)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"play_sound",children:(0,t.jsx)(n.code,{children:"play_sound()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.play_sound(\n sound_path: string,\n index: int,\n x: FixedPoint,\n y: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Plays the sound described at ",(0,t.jsx)(n.code,{children:"sound_path"})," at the in-game location of ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'pewpew.play_sound("/dynamic/my_custom_sound.lua", 0, 100fx, 100fx)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"create_explosion",children:(0,t.jsx)(n.code,{children:"create_explosion()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.create_explosion(\n x: FixedPoint,\n y: FixedPoint,\n color: int,\n scale: FixedPoint,\n particle_count: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates an explosion of particles at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),". ",(0,t.jsx)(n.code,{children:"color"})," specifies the color of the explosion. ",(0,t.jsx)(n.code,{children:"scale"})," describes how large the explosion will be. It should be in the range ]0, 10], with 1 being an average explosion. ",(0,t.jsx)(n.code,{children:"particle_count"})," specifies the number of particles that make up the explosion. It must be in the range [1, 100]."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"pewpew.create_explosion(200fx, 100fx, 0xffffffff, 1fx, 20) -- medium explosion\npewpew.create_explosion(300fx, 100fx, 0xffffffff, 3fx, 50) -- large red explosion\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_asteroid",children:(0,t.jsx)(n.code,{children:"new_asteroid()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_asteroid(\n x: FixedPoint,\n y: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Asteroid at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"})," and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_asteroid_with_size",children:(0,t.jsx)(n.code,{children:"new_asteroid_with_size()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_asteroid_with_size(\n x: FixedPoint,\n y: FixedPoint,\n size: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Asteroid at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"})," with an AsteroidSize given by ",(0,t.jsx)(n.code,{children:"size"})," and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_baf",children:(0,t.jsx)(n.code,{children:"new_baf()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_baf(\n x: FixedPoint,\n y: FixedPoint,\n angle: FixedPoint,\n speed: FixedPoint,\n lifetime: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new BAF at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId. ",(0,t.jsx)(n.code,{children:"angle"})," specifies the angle at which the BAF will move. ",(0,t.jsx)(n.code,{children:"speed"})," specifies the maximum speed it will reach. ",(0,t.jsx)(n.code,{children:"lifetime"})," indicates the number of game ticks after which the BAF is destroyed the next time it hits a wall. Specify a negative ",(0,t.jsx)(n.code,{children:"lifetime"})," to create a BAF that lives forever."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_baf_red",children:(0,t.jsx)(n.code,{children:"new_baf_red()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_baf_red(\n x: FixedPoint,\n y: FixedPoint,\n angle: FixedPoint,\n speed: FixedPoint,\n lifetime: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new red BAF at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId. A red BAF has more health points than a regular BAF. ",(0,t.jsx)(n.code,{children:"angle"})," specifies the angle at which the BAF will move. ",(0,t.jsx)(n.code,{children:"speed"})," specifies the maximum speed it will reach. ",(0,t.jsx)(n.code,{children:"lifetime"})," indicates the number of game ticks after which the BAF is destroyed the next time it hits a wall. Specify a negative ",(0,t.jsx)(n.code,{children:"lifetime"})," to create a BAF that lives forever."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_baf_blue",children:(0,t.jsx)(n.code,{children:"new_baf_blue()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_baf_blue(\n x: FixedPoint,\n y: FixedPoint,\n angle: FixedPoint,\n speed: FixedPoint,\n lifetime: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new blue BAF at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId. A blue BAF bounces on walls with a slightly randomized angle. ",(0,t.jsx)(n.code,{children:"angle"})," specifies the angle at which the BAF will move. ",(0,t.jsx)(n.code,{children:"speed"})," specifies the maximum speed it will reach. ",(0,t.jsx)(n.code,{children:"lifetime"})," indicates the number of game ticks after which the BAF is destroyed the next time it hits a wall. Specify a negative ",(0,t.jsx)(n.code,{children:"lifetime"})," to create a BAF that lives forever."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_bomb",children:(0,t.jsx)(n.code,{children:"new_bomb()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_bomb(\n x: FixedPoint,\n y: FixedPoint,\n type: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Bomb at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"pewpew.new_bomb(10fx, 10fx, pewpew.BombType.SMALL_ATOMIZE)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_bonus",children:(0,t.jsx)(n.code,{children:"new_bonus()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_bonus(\n x: FixedPoint,\n y: FixedPoint,\n type: int,\n config: table {\n box_duration: int,\n cannon: int,\n frequency: int,\n weapon_duration: int,\n number_of_shields: int,\n speed_factor: FixedPoint,\n speed_offset: FixedPoint,\n speed_duration: int,\n taken_callback: function\n }\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Bonus at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"})," of the type ",(0,t.jsx)(n.code,{children:"type"}),", and returns its entityId.\nFor shield bonuses, the option ",(0,t.jsx)(n.code,{children:"number_of_shields"})," determines how many shields are given out.\nFor weapon bonuses, the options ",(0,t.jsx)(n.code,{children:"cannon"}),", ",(0,t.jsx)(n.code,{children:"frequency"}),", ",(0,t.jsx)(n.code,{children:"weapon_duration"})," have the same meaning as in ",(0,t.jsx)(n.code,{children:"pewpew.configure_player_ship_weapon"}),".\nFor speed bonuses, the options ",(0,t.jsx)(n.code,{children:"speed_factor"}),", ",(0,t.jsx)(n.code,{children:"speed_offset"}),",and ",(0,t.jsx)(n.code,{children:"speed_duration"})," have the same meaning as in ",(0,t.jsx)(n.code,{children:"set_player_speed"}),". ",(0,t.jsx)(n.code,{children:"taken_callback"})," is called when the bonus is taken, and is mandatory for the reinstantiation bonus. The callback receives as arguments the entity id of the bonus, the player id, and the ship's entity id.\nThe default box duration is 400 ticks."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"pewpew.new_bonus(10fx, 10fx, pewpew.BonusType.WEAPON, {cannon = pewpew.CannonType.TIC_TOC, frequency = pewpew.CannonFrequency.FREQ_5, weapon_duration = 100})\npewpew.new_bonus(10fx, 10fx, pewpew.BonusType.SHIELD, {number_of_shields = 3})\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_crowder",children:(0,t.jsx)(n.code,{children:"new_crowder()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_crowder(\n x: FixedPoint,\n y: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Crowder at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_floating_message",children:(0,t.jsx)(n.code,{children:"new_floating_message()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_floating_message(\n x: FixedPoint,\n y: FixedPoint,\n str: string,\n config: table {\n scale: FixedPoint,\n ticks_before_fade: int,\n is_optional: bool\n }\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new floating message at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", with ",(0,t.jsx)(n.code,{children:"str"})," as the message. The scale is a number that determines how large the message will be. ",(0,t.jsx)(n.code,{children:"1"})," is the default scale. ",(0,t.jsx)(n.code,{children:"ticks_before_fade"})," determines how many ticks occur before the message starts to fade out. ",(0,t.jsx)(n.code,{children:"is_optional"})," can be used to tell the game if the message can be hidden depending on the user's UI settings.\nIf not specified, ",(0,t.jsx)(n.code,{children:"scale"})," is 1, ",(0,t.jsx)(n.code,{children:"ticks_before_fade"})," is 30 and ",(0,t.jsx)(n.code,{children:"is_optional"})," is ",(0,t.jsx)(n.code,{children:"false"}),".\nReturns the floating message's entityId."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'pewpew.new_floating_message(10fx, 10fx, "hello", {scale = 2fx, ticks_before_fade = 60, is_optional = true})\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_customizable_entity",children:(0,t.jsx)(n.code,{children:"new_customizable_entity()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_customizable_entity(\n x: FixedPoint,\n y: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new customizable entity at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_inertiac",children:(0,t.jsx)(n.code,{children:"new_inertiac()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_inertiac(\n x: FixedPoint,\n y: FixedPoint,\n acceleration: FixedPoint,\n angle: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Inertiac at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId. The inertiac will accelerate according to ",(0,t.jsx)(n.code,{children:"acceleration"}),". It spawns with a random velocity in a direction specified by ",(0,t.jsx)(n.code,{children:"angle"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_mothership",children:(0,t.jsx)(n.code,{children:"new_mothership()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_mothership(\n x: FixedPoint,\n y: FixedPoint,\n type: int,\n angle: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Mothership at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"pewpew.new_mothership(50fx, 50fx, pewpew.MothershipType.THREE_CORNERS, fmath.tau() / 4fx)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_pointonium",children:(0,t.jsx)(n.code,{children:"new_pointonium()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_pointonium(\n x: FixedPoint,\n y: FixedPoint,\n value: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Pointonium at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),". Value must be 64, 128, or 256."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_player_ship",children:(0,t.jsx)(n.code,{children:"new_player_ship()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_player_ship(\n x: FixedPoint,\n y: FixedPoint,\n player_index: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Player Ship at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"})," for the player identified by ",(0,t.jsx)(n.code,{children:"player_index"}),", and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_player_bullet",children:(0,t.jsx)(n.code,{children:"new_player_bullet()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_player_bullet(\n x: FixedPoint,\n y: FixedPoint,\n angle: FixedPoint,\n player_index: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new bullet at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"})," with the angle ",(0,t.jsx)(n.code,{children:"angle"})," belonging to the player at the index ",(0,t.jsx)(n.code,{children:"player_index"}),". Returns the entityId of the bullet."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_rolling_cube",children:(0,t.jsx)(n.code,{children:"new_rolling_cube()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_rolling_cube(\n x: FixedPoint,\n y: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Rolling Cube at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_rolling_sphere",children:(0,t.jsx)(n.code,{children:"new_rolling_sphere()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_rolling_sphere(\n x: FixedPoint,\n y: FixedPoint,\n angle: FixedPoint,\n speed: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Rolling Sphere at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_wary",children:(0,t.jsx)(n.code,{children:"new_wary()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_wary(\n x: FixedPoint,\n y: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Wary at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_ufo",children:(0,t.jsx)(n.code,{children:"new_ufo()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_ufo(\n x: FixedPoint,\n y: FixedPoint,\n dx: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new UFO at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"})," moving horizontally at the speed of ",(0,t.jsx)(n.code,{children:"dx"}),", and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"rolling_cube_set_enable_collisions_with_walls",children:(0,t.jsx)(n.code,{children:"rolling_cube_set_enable_collisions_with_walls()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.rolling_cube_set_enable_collisions_with_walls(\n entity_id: EntityId,\n collide_with_walls: bool\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets whether the rolling cube identified with ",(0,t.jsx)(n.code,{children:"id"})," collides with walls. By default it does not."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local x,y = pewpew.rolling_cube_set_enable_collisions_with_walls(id, true)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"ufo_set_enable_collisions_with_walls",children:(0,t.jsx)(n.code,{children:"ufo_set_enable_collisions_with_walls()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.ufo_set_enable_collisions_with_walls(\n entity_id: EntityId,\n collide_with_walls: bool\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets whether the ufo identified with ",(0,t.jsx)(n.code,{children:"id"})," collides with walls. By default it does not."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local x,y = pewpew.ufo_set_enable_collisions_with_walls(id, true)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_get_position",children:(0,t.jsx)(n.code,{children:"entity_get_position()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_get_position(entity_id: EntityId): FixedPoint, FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the position of the entity identified by ",(0,t.jsx)(n.code,{children:"id"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local x,y = pewpew.entity_get_position(entity_id)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_get_is_alive",children:(0,t.jsx)(n.code,{children:"entity_get_is_alive()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_get_is_alive(entity_id: EntityId): bool\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns whether the entity identified by ",(0,t.jsx)(n.code,{children:"id"})," is alive or not."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_get_is_started_to_be_destroyed",children:(0,t.jsx)(n.code,{children:"entity_get_is_started_to_be_destroyed()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_get_is_started_to_be_destroyed(entity_id: EntityId): bool\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns whether the entity identified by ",(0,t.jsx)(n.code,{children:"id"})," is in the process of being destroyed. Returns false if the entity does not exist."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_set_position",children:(0,t.jsx)(n.code,{children:"entity_set_position()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_set_position(\n entity_id: EntityId,\n x: FixedPoint,\n y: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the position of the entity identified by ",(0,t.jsx)(n.code,{children:"id"})," to ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_set_radius",children:(0,t.jsx)(n.code,{children:"entity_set_radius()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_set_radius(\n entity_id: EntityId,\n radius: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the radius of the entity identified by ",(0,t.jsx)(n.code,{children:"id"}),". To give you a sense of scale, motherships have a radius of 28fx."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_set_update_callback",children:(0,t.jsx)(n.code,{children:"entity_set_update_callback()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_set_update_callback(\n entity_id: EntityId,\n callback: function\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets a callback that will be called at every tick as long as the entity identified by ",(0,t.jsx)(n.code,{children:"id"})," is alive. Remove the callback by passing a nil ",(0,t.jsx)(n.code,{children:"callback"}),". The callbacks gets called with the entity ID."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local function my_update_callback(entity_id)\n local x,y = pewpew.entity_get_position(entity_id)\n pewpew.entity_set_position(entity_id, x + 2fx, y) -- move the entity to the right\nend\npewpew.entity_set_update_callback(entity_id, my_update_callback)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_destroy",children:(0,t.jsx)(n.code,{children:"entity_destroy()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_destroy(entity_id: EntityId)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Makes the entity identified by ",(0,t.jsx)(n.code,{children:"id"})," immediately disappear forever."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_react_to_weapon",children:(0,t.jsx)(n.code,{children:"entity_react_to_weapon()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_react_to_weapon(\n entity_id: EntityId,\n weapon: table {\n type: int,\n x: FixedPoint,\n y: FixedPoint,\n player_index: int\n }\n): bool\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Makes the entity identified by ",(0,t.jsx)(n.code,{children:"id"})," react to the weapon described in ",(0,t.jsx)(n.code,{children:"weapon_description"}),". Returns whether the entity reacted to the weapon. The returned value is typically used to decide whether the weapon should continue to exist or not. In the case of an explosion, ",(0,t.jsx)(n.code,{children:"x"})," and ",(0,t.jsx)(n.code,{children:"y"})," should store the origin of the explosion. In the case of a bullet, ",(0,t.jsx)(n.code,{children:"x"})," and ",(0,t.jsx)(n.code,{children:"y"})," should store the vector of the bullet. The player identified by ",(0,t.jsx)(n.code,{children:"player_index"})," will be assigned points. If ",(0,t.jsx)(n.code,{children:"player_index"})," is invalid, no player will be assigned points."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_position_interpolation",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_position_interpolation()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_position_interpolation(\n entity_id: EntityId,\n enable: bool\n)\n"})}),"\n",(0,t.jsx)(n.p,{children:"Sets whether the position of the mesh wil be interpolated when rendering. In general, this should be set to true if the entity will be moving smoothly."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_mesh",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_mesh(\n entity_id: EntityId,\n file_path: string,\n index: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"})," to the mesh described in the file ",(0,t.jsx)(n.code,{children:"file_path"})," at the index ",(0,t.jsx)(n.code,{children:"index"}),". ",(0,t.jsx)(n.code,{children:"index"})," starts at 0. If ",(0,t.jsx)(n.code,{children:"file_path"})," is an empty string, the mesh is removed."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'local id = pewpew.new_customizable_entity(0fx, 0fx)\npewpew.customizable_entity_set_mesh(id, "/dynamic/graphics.lua", 0)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_flipping_meshes",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_flipping_meshes()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_flipping_meshes(\n entity_id: EntityId,\n file_path: string,\n index_0: int,\n index_1: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Similar to ",(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh"}),", but sets two meshes that will be used in alternation. By specifying 2 separate meshes, 60 fps animations can be achieved."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'local id = pewpew.new_customizable_entity(0fx, 0fx)\npewpew.customizable_entity_set_flipping_meshes(id, "/dynamic/graphics.lua", 0, 1)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_mesh_color",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh_color()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_mesh_color(\n entity_id: EntityId,\n color: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the color multiplier for the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_string",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_string()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_string(\n entity_id: EntityId,\n text: string\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the string to be displayed as part of the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_mesh_xyz",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh_xyz()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_mesh_xyz(\n entity_id: EntityId,\n x: FixedPoint,\n y: FixedPoint,\n z: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the position of the mesh to x,y,z, relative to the center ofthe customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_mesh_z",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh_z()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_mesh_z(\n entity_id: EntityId,\n z: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the height of the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"}),". A ",(0,t.jsx)(n.code,{children:"z"})," greater to 0 makes the mesh be closer, while a ",(0,t.jsx)(n.code,{children:"z"})," less than 0 makes the mesh be further away."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_mesh_scale",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh_scale()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_mesh_scale(\n entity_id: EntityId,\n scale: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the scale of the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"}),". A ",(0,t.jsx)(n.code,{children:"scale"})," less than 1 makes the mesh appear smaller, while a ",(0,t.jsx)(n.code,{children:"scale"})," greater than 1 makes the mesh appear larger."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_mesh_xyz_scale",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh_xyz_scale()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_mesh_xyz_scale(\n entity_id: EntityId,\n x_scale: FixedPoint,\n y_scale: FixedPoint,\n z_scale: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the scale of the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"})," along the x,y,z axis. A ",(0,t.jsx)(n.code,{children:"scale"})," less than 1 makes the mesh appear smaller, while a ",(0,t.jsx)(n.code,{children:"scale"})," greater than 1 makes the mesh appear larger."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_mesh_angle",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh_angle()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_mesh_angle(\n entity_id: EntityId,\n angle: FixedPoint,\n x_axis: FixedPoint,\n y_axis: FixedPoint,\n z_axis: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the rotation angle of the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"}),". The rotation is applied along the axis defined by ",(0,t.jsx)(n.code,{children:"x_axis"}),",",(0,t.jsx)(n.code,{children:"y_axis"}),",",(0,t.jsx)(n.code,{children:"z_axis"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"-- Rotate the entity by 45 degrees along the z_axis\npewpew.customizable_entity_set_mesh_angle(entity_id, fmath.tau() / 8fx, 0fx, 0fx, 1fx)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_skip_mesh_attributes_interpolation",children:(0,t.jsx)(n.code,{children:"customizable_entity_skip_mesh_attributes_interpolation()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_skip_mesh_attributes_interpolation(entity_id: EntityId)\n"})}),"\n",(0,t.jsx)(n.p,{children:"Skips the interpolation of the mesh's attributes (x, y, z, scale_x, scale_y, scale_z, rotation)."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_configure_music_response",children:(0,t.jsx)(n.code,{children:"customizable_entity_configure_music_response()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_configure_music_response(\n entity_id: EntityId,\n config: table {\n color_start: int,\n color_end: int,\n scale_x_start: FixedPoint,\n scale_x_end: FixedPoint,\n scale_y_start: FixedPoint,\n scale_y_end: FixedPoint,\n scale_z_start: FixedPoint,\n scale_z_end: FixedPoint\n }\n)\n"})}),"\n",(0,t.jsx)(n.p,{children:"Configures the way the entity is going to respond to the music."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:" -- Makes the entity larger\n pewpew.customizable_entity_configure_music_response(entity_id, {scale_x_start = 1fx, scale_x_end = 2fx})\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_add_rotation_to_mesh",children:(0,t.jsx)(n.code,{children:"customizable_entity_add_rotation_to_mesh()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_add_rotation_to_mesh(\n entity_id: EntityId,\n angle: FixedPoint,\n x_axis: FixedPoint,\n y_axis: FixedPoint,\n z_axis: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Adds a rotation to the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"}),". The rotation is applied along the axis defined by ",(0,t.jsx)(n.code,{children:"x_axis"}),",",(0,t.jsx)(n.code,{children:"y_axis"}),",",(0,t.jsx)(n.code,{children:"z_axis"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"-- Rotate the entity by 45 degrees along the z_axis\npewpew.customizable_entity_add_rotation_to_mesh(entity_id, fmath.tau() / 8fx, 0fx, 0fx, 1fx)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_visibility_radius",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_visibility_radius()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_visibility_radius(\n entity_id: EntityId,\n radius: FixedPoint\n)\n"})}),"\n",(0,t.jsx)(n.p,{children:"Sets the radius defining the visibility of the entity. This allows the game to know when an entity is actually visible, which in turns allows to massively optimize the rendering. Use the smallest value possible. If not set, the rendering radius is an unspecified large number that effectively makes the entity always be rendered, even if not visible."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_configure_wall_collision",children:(0,t.jsx)(n.code,{children:"customizable_entity_configure_wall_collision()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_configure_wall_collision(\n entity_id: EntityId,\n collide_with_walls: bool,\n collision_callback: function\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"collide_with_walls"})," configures whether the entity should stop when colliding with walls. If ",(0,t.jsx)(n.code,{children:"collision_callback"})," is not nil, it is called anytime a collision is detected. The callback gets called with the entity id of the entity withthe callback, and with the normal to the wall."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'function my_wall_collision_callback(entity_id, wall_normal_x, wall_normal_y)\n pewpew.print("A wall collision happened with entity " .. entity_id)\nend\nlocal id = pewpew.new_customizable_entity(100fx, 100fx)\npewpew.customizable_entity_configure_wall_collision(id, my_wall_collision_callback)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_player_collision_callback",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_player_collision_callback()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_player_collision_callback(\n entity_id: EntityId,\n collision_callback: function\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the callback for when the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"})," collides with a player's ship. The callback gets called with the entity id of the entity with the callback, and the player_index and ship_id that were involved in the collision. Don't forget to set a radius on the customizable entity, otherwise no collisions will be detected."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'function my_collision_callback(entity_id, player_index, ship_entity_id)\n pewpew.print("The entity: " .. entity_id)\n pewpew.print("Collided with the ship: " .. ship_entity_id)\n pewpew.print("That belongs to the player: " .. player_index)\nend\nlocal id = pewpew.new_customizable_entity(100fx, 100fx)\npewpew.customizable_entity_set_player_collision_callback(id, my_collision_callback)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_weapon_collision_callback",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_weapon_collision_callback()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_weapon_collision_callback(\n entity_id: EntityId,\n weapon_collision_callback: function\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the callback for when the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"})," collides with a player's weapon. The callback gets called with the entity_id of the entity on which the callback is set, the player_index of the player that triggered the weapon, and the type of the weapon. The callback ",(0,t.jsx)(n.em,{children:"must"})," return a boolean saying whether the entity reacts to the weapon. In the case of a bullet, this boolean determines whether the bullet should be destroyed."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'local id = pewpew.new_customizable_entity(100fx, 100fx)\npewpew.customizable_entity_set_weapon_collision_callback(id, function(entity_id, player_index, weapon_type)\n pewpew.print("Collided with weapon from player: " .. player_index)\n if weapon_type == pewpew.WeaponType.BULLET then\n pewpew.print("Collided with bullet!")\n end\n return true\nend)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_start_spawning",children:(0,t.jsx)(n.code,{children:"customizable_entity_start_spawning()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_start_spawning(\n entity_id: EntityId,\n spawning_duration: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Makes the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"})," spawn for a duration of ",(0,t.jsx)(n.code,{children:"spawning_duration"})," game ticks."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_start_exploding",children:(0,t.jsx)(n.code,{children:"customizable_entity_start_exploding()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_start_exploding(\n entity_id: EntityId,\n explosion_duration: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Makes the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"})," explode for a duration of ",(0,t.jsx)(n.code,{children:"explosion_duration"})," game ticks. After the explosion, the entity is destroyed. ",(0,t.jsx)(n.code,{children:"explosion_duration"})," must be less than 255. Any scale applied to the entity is also applied to the explosion."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(r,{...e})}):r(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>c});var t=i(6540);const s={},l=t.createContext(s);function d(e){const n=t.useContext(l);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),t.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/4315fc58.bc93d473.js b/assets/js/4315fc58.bc93d473.js deleted file mode 100644 index abc2444..0000000 --- a/assets/js/4315fc58.bc93d473.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[7376],{2804:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>d,default:()=>h,frontMatter:()=>l,metadata:()=>c,toc:()=>o});var t=i(4848),s=i(8453);const l={sidebar_position:2},d="pewpew library",c={id:"APIs/PewPew",title:"PewPew",description:"The pewpew library contains all the functions for configuring levels and managing entities.",source:"@site/docs/APIs/PewPew.md",sourceDirName:"APIs",slug:"/APIs/PewPew",permalink:"/docs/APIs/PewPew",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/APIs/PewPew.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Types",permalink:"/docs/APIs/types"},next:{title:"Fmath",permalink:"/docs/APIs/Fmath"}},a={},o=[{value:"Enums",id:"enums",level:2},{value:"EntityType",id:"entitytype",level:3},{value:"MothershipType",id:"mothershiptype",level:3},{value:"CannonType",id:"cannontype",level:3},{value:"CannonFrequency",id:"cannonfrequency",level:3},{value:"BombType",id:"bombtype",level:3},{value:"BonusType",id:"bonustype",level:3},{value:"WeaponType",id:"weapontype",level:3},{value:"AsteroidSize",id:"asteroidsize",level:3},{value:"Functions",id:"functions",level:2},{value:"print()",id:"print",level:3},{value:"print_debug_info()",id:"print_debug_info",level:3},{value:"set_level_size()",id:"set_level_size",level:3},{value:"add_wall()",id:"add_wall",level:3},{value:"remove_wall()",id:"remove_wall",level:3},{value:"add_update_callback()",id:"add_update_callback",level:3},{value:"get_number_of_players()",id:"get_number_of_players",level:3},{value:"increase_score_of_player()",id:"increase_score_of_player",level:3},{value:"increase_score_streak_of_player()",id:"increase_score_streak_of_player",level:3},{value:"get_score_streak_level()",id:"get_score_streak_level",level:3},{value:"stop_game()",id:"stop_game",level:3},{value:"get_player_inputs()",id:"get_player_inputs",level:3},{value:"get_score_of_player()",id:"get_score_of_player",level:3},{value:"configure_player()",id:"configure_player",level:3},{value:"configure_player_hud()",id:"configure_player_hud",level:3},{value:"get_player_configuration()",id:"get_player_configuration",level:3},{value:"configure_player_ship_weapon()",id:"configure_player_ship_weapon",level:3},{value:"add_damage_to_player_ship()",id:"add_damage_to_player_ship",level:3},{value:"add_arrow_to_player_ship()",id:"add_arrow_to_player_ship",level:3},{value:"remove_arrow_from_player_ship()",id:"remove_arrow_from_player_ship",level:3},{value:"make_player_ship_transparent()",id:"make_player_ship_transparent",level:3},{value:"set_player_ship_speed()",id:"set_player_ship_speed",level:3},{value:"get_all_entities()",id:"get_all_entities",level:3},{value:"get_entities_colliding_with_disk()",id:"get_entities_colliding_with_disk",level:3},{value:"get_entity_count()",id:"get_entity_count",level:3},{value:"get_entity_type()",id:"get_entity_type",level:3},{value:"play_ambient_sound()",id:"play_ambient_sound",level:3},{value:"play_sound()",id:"play_sound",level:3},{value:"create_explosion()",id:"create_explosion",level:3},{value:"new_asteroid()",id:"new_asteroid",level:3},{value:"new_asteroid_with_size()",id:"new_asteroid_with_size",level:3},{value:"new_baf()",id:"new_baf",level:3},{value:"new_baf_red()",id:"new_baf_red",level:3},{value:"new_baf_blue()",id:"new_baf_blue",level:3},{value:"new_bomb()",id:"new_bomb",level:3},{value:"new_bonus()",id:"new_bonus",level:3},{value:"new_crowder()",id:"new_crowder",level:3},{value:"new_floating_message()",id:"new_floating_message",level:3},{value:"new_customizable_entity()",id:"new_customizable_entity",level:3},{value:"new_inertiac()",id:"new_inertiac",level:3},{value:"new_mothership()",id:"new_mothership",level:3},{value:"new_pointonium()",id:"new_pointonium",level:3},{value:"new_player_ship()",id:"new_player_ship",level:3},{value:"new_player_bullet()",id:"new_player_bullet",level:3},{value:"new_rolling_cube()",id:"new_rolling_cube",level:3},{value:"new_rolling_sphere()",id:"new_rolling_sphere",level:3},{value:"new_wary()",id:"new_wary",level:3},{value:"new_ufo()",id:"new_ufo",level:3},{value:"rolling_cube_set_enable_collisions_with_walls()",id:"rolling_cube_set_enable_collisions_with_walls",level:3},{value:"ufo_set_enable_collisions_with_walls()",id:"ufo_set_enable_collisions_with_walls",level:3},{value:"entity_get_position()",id:"entity_get_position",level:3},{value:"entity_get_is_alive()",id:"entity_get_is_alive",level:3},{value:"entity_get_is_started_to_be_destroyed()",id:"entity_get_is_started_to_be_destroyed",level:3},{value:"entity_set_position()",id:"entity_set_position",level:3},{value:"entity_set_radius()",id:"entity_set_radius",level:3},{value:"entity_set_update_callback()",id:"entity_set_update_callback",level:3},{value:"entity_destroy()",id:"entity_destroy",level:3},{value:"entity_react_to_weapon()",id:"entity_react_to_weapon",level:3},{value:"customizable_entity_set_position_interpolation()",id:"customizable_entity_set_position_interpolation",level:3},{value:"customizable_entity_set_mesh()",id:"customizable_entity_set_mesh",level:3},{value:"customizable_entity_set_flipping_meshes()",id:"customizable_entity_set_flipping_meshes",level:3},{value:"customizable_entity_set_mesh_color()",id:"customizable_entity_set_mesh_color",level:3},{value:"customizable_entity_set_string()",id:"customizable_entity_set_string",level:3},{value:"customizable_entity_set_mesh_xyz()",id:"customizable_entity_set_mesh_xyz",level:3},{value:"customizable_entity_set_mesh_z()",id:"customizable_entity_set_mesh_z",level:3},{value:"customizable_entity_set_mesh_scale()",id:"customizable_entity_set_mesh_scale",level:3},{value:"customizable_entity_set_mesh_xyz_scale()",id:"customizable_entity_set_mesh_xyz_scale",level:3},{value:"customizable_entity_set_mesh_angle()",id:"customizable_entity_set_mesh_angle",level:3},{value:"customizable_entity_skip_mesh_attributes_interpolation()",id:"customizable_entity_skip_mesh_attributes_interpolation",level:3},{value:"customizable_entity_configure_music_response()",id:"customizable_entity_configure_music_response",level:3},{value:"customizable_entity_add_rotation_to_mesh()",id:"customizable_entity_add_rotation_to_mesh",level:3},{value:"customizable_entity_set_visibility_radius()",id:"customizable_entity_set_visibility_radius",level:3},{value:"customizable_entity_configure_wall_collision()",id:"customizable_entity_configure_wall_collision",level:3},{value:"customizable_entity_set_player_collision_callback()",id:"customizable_entity_set_player_collision_callback",level:3},{value:"customizable_entity_set_weapon_collision_callback()",id:"customizable_entity_set_weapon_collision_callback",level:3},{value:"customizable_entity_start_spawning()",id:"customizable_entity_start_spawning",level:3},{value:"customizable_entity_start_exploding()",id:"customizable_entity_start_exploding",level:3}];function r(e){const n={blockquote:"blockquote",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",hr:"hr",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"pewpew-library",children:"pewpew library"}),"\n",(0,t.jsxs)(n.p,{children:["The ",(0,t.jsx)(n.code,{children:"pewpew"})," library contains all the functions for configuring levels and managing entities."]}),"\n",(0,t.jsx)(n.h2,{id:"enums",children:"Enums"}),"\n",(0,t.jsx)(n.h3,{id:"entitytype",children:"EntityType"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"ASTEROID"}),"\n",(0,t.jsx)(n.li,{children:"BAF"}),"\n",(0,t.jsx)(n.li,{children:"INERTIAC"}),"\n",(0,t.jsx)(n.li,{children:"MOTHERSHIP"}),"\n",(0,t.jsx)(n.li,{children:"MOTHERSHIP_BULLET"}),"\n",(0,t.jsx)(n.li,{children:"ROLLING_CUBE"}),"\n",(0,t.jsx)(n.li,{children:"ROLLING_SPHERE"}),"\n",(0,t.jsx)(n.li,{children:"UFO"}),"\n",(0,t.jsx)(n.li,{children:"WARY"}),"\n",(0,t.jsx)(n.li,{children:"CROWDER"}),"\n",(0,t.jsx)(n.li,{children:"CUSTOMIZABLE_ENTITY"}),"\n",(0,t.jsx)(n.li,{children:"SHIP"}),"\n",(0,t.jsx)(n.li,{children:"BOMB"}),"\n",(0,t.jsx)(n.li,{children:"BAF_BLUE"}),"\n",(0,t.jsx)(n.li,{children:"BAF_RED"}),"\n",(0,t.jsx)(n.li,{children:"WARY_MISSILE"}),"\n",(0,t.jsx)(n.li,{children:"UFO_BULLET"}),"\n",(0,t.jsx)(n.li,{children:"PLAYER_BULLET"}),"\n",(0,t.jsx)(n.li,{children:"BOMB_EXPLOSION"}),"\n",(0,t.jsx)(n.li,{children:"PLAYER_EXPLOSION"}),"\n",(0,t.jsx)(n.li,{children:"BONUS"}),"\n",(0,t.jsx)(n.li,{children:"FLOATING_MESSAGE"}),"\n",(0,t.jsx)(n.li,{children:"POINTONIUM"}),"\n",(0,t.jsx)(n.li,{children:"BONUS_IMPLOSION"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"mothershiptype",children:"MothershipType"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"THREE_CORNERS"}),"\n",(0,t.jsx)(n.li,{children:"FOUR_CORNERS"}),"\n",(0,t.jsx)(n.li,{children:"FIVE_CORNERS"}),"\n",(0,t.jsx)(n.li,{children:"SIX_CORNERS"}),"\n",(0,t.jsx)(n.li,{children:"SEVEN_CORNERS"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"cannontype",children:"CannonType"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"SINGLE"}),"\n",(0,t.jsx)(n.li,{children:"TIC_TOC"}),"\n",(0,t.jsx)(n.li,{children:"DOUBLE"}),"\n",(0,t.jsx)(n.li,{children:"TRIPLE"}),"\n",(0,t.jsx)(n.li,{children:"FOUR_DIRECTIONS"}),"\n",(0,t.jsx)(n.li,{children:"DOUBLE_SWIPE"}),"\n",(0,t.jsx)(n.li,{children:"HEMISPHERE"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"cannonfrequency",children:"CannonFrequency"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"FREQ_30"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_15"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_10"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_7_5"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_6"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_5"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_3"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_2"}),"\n",(0,t.jsx)(n.li,{children:"FREQ_1"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"bombtype",children:"BombType"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"FREEZE"}),"\n",(0,t.jsx)(n.li,{children:"REPULSIVE"}),"\n",(0,t.jsx)(n.li,{children:"ATOMIZE"}),"\n",(0,t.jsx)(n.li,{children:"SMALL_ATOMIZE"}),"\n",(0,t.jsx)(n.li,{children:"SMALL_FREEZE"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"bonustype",children:"BonusType"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"REINSTANTIATION"}),"\n",(0,t.jsx)(n.li,{children:"SHIELD"}),"\n",(0,t.jsx)(n.li,{children:"SPEED"}),"\n",(0,t.jsx)(n.li,{children:"WEAPON"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"weapontype",children:"WeaponType"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"BULLET"}),"\n",(0,t.jsx)(n.li,{children:"FREEZE_EXPLOSION"}),"\n",(0,t.jsx)(n.li,{children:"REPULSIVE_EXPLOSION"}),"\n",(0,t.jsx)(n.li,{children:"ATOMIZE_EXPLOSION"}),"\n"]}),"\n",(0,t.jsx)(n.h3,{id:"asteroidsize",children:"AsteroidSize"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsx)(n.li,{children:"SMALL"}),"\n",(0,t.jsx)(n.li,{children:"MEDIUM"}),"\n",(0,t.jsx)(n.li,{children:"LARGE"}),"\n",(0,t.jsx)(n.li,{children:"VERY_LARGE"}),"\n"]}),"\n",(0,t.jsx)(n.h2,{id:"functions",children:"Functions"}),"\n",(0,t.jsx)(n.h3,{id:"print",children:(0,t.jsx)(n.code,{children:"print()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.print(str: string)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Prints ",(0,t.jsx)(n.code,{children:"str"})," in the console for debugging."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'local some_number = 42\npewpew.print("the value of some_number is: " .. some_number)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"print_debug_info",children:(0,t.jsx)(n.code,{children:"print_debug_info()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.print_debug_info()\n"})}),"\n",(0,t.jsx)(n.p,{children:"Prints debug info: the number of entities created and the amount of memory used by the script."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"pewpew.print_debug_info()\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"set_level_size",children:(0,t.jsx)(n.code,{children:"set_level_size()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.set_level_size(\n width: FixedPoint,\n height: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the level's size. Implicetely adds walls to make sure that entities can not go outside of the level's boundaries. ",(0,t.jsx)(n.code,{children:"width"})," and ",(0,t.jsx)(n.code,{children:"height"})," are clamped to the range ]0fx, 6000fx]. If this function is not called, the level size is (10fx, 10fx), which is uselessly small for most cases."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local width = 300fx\nlocal height = 200fx\npewpew.set_level_size(width, height)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"add_wall",children:(0,t.jsx)(n.code,{children:"add_wall()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.add_wall(\n start_x: FixedPoint,\n start_y: FixedPoint,\n end_x: FixedPoint,\n end_y: FixedPoint\n): int\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Adds a wall to the level from (",(0,t.jsx)(n.code,{children:"start_x"}),",",(0,t.jsx)(n.code,{children:"start_y"}),") to (",(0,t.jsx)(n.code,{children:"end_x"}),",",(0,t.jsx)(n.code,{children:"end_y"}),"), and returns its wall ID. A maximum of 200 walls can be added to a level."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"pewpew.add_wall(100fx, 100fx, 200fx, 200fx)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"remove_wall",children:(0,t.jsx)(n.code,{children:"remove_wall()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.remove_wall(wall_id: int)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Remove the wall with the given ",(0,t.jsx)(n.code,{children:"wall_id"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local wall_id = pewpew.add_wall(100fx, 100fx, 200fx, 200fx)\n-- Later, when the wall needs to be removed:\npewpew.remove_wall(wall_id)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"add_update_callback",children:(0,t.jsx)(n.code,{children:"add_update_callback()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.add_update_callback(update_callback: function)\n"})}),"\n",(0,t.jsx)(n.p,{children:"Adds a callback that will be updated at each game tick."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'local tick_count = 0\npewpew.add_update_callback(function()\n pewpew.print("this is tick " .. tick_count)\n tick_count = tick_count + 1\nend)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_number_of_players",children:(0,t.jsx)(n.code,{children:"get_number_of_players()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_number_of_players(): int\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns the number of players in the game."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"increase_score_of_player",children:(0,t.jsx)(n.code,{children:"increase_score_of_player()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.increase_score_of_player(\n player_index: int,\n delta: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Increases the score of the player at the specified ",(0,t.jsx)(n.code,{children:"player_index"})," by an amount of ",(0,t.jsx)(n.code,{children:"delta"}),". ",(0,t.jsx)(n.code,{children:"player_index"})," must in the range [0, get_number_of_players() - 1]. Note that ",(0,t.jsx)(n.code,{children:"delta"})," can be negative."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"increase_score_streak_of_player",children:(0,t.jsx)(n.code,{children:"increase_score_streak_of_player()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.increase_score_streak_of_player(\n player_index: int,\n delta: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Increases the score streak counter of the player at the specified ",(0,t.jsx)(n.code,{children:"player_index"})," by an amount of ",(0,t.jsx)(n.code,{children:"delta"}),". This counter is used to determine at which level of score streak the player is at. In turn, the score streak level is used to determine how much pointonium is given. Typically the score streak counter should be increased when an enemy is destroyed with the same score that the enemy provide. ",(0,t.jsx)(n.code,{children:"player_index"})," must in the range [0, get_number_of_players() - 1]. Note that ",(0,t.jsx)(n.code,{children:"delta"})," can be negative."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_score_streak_level",children:(0,t.jsx)(n.code,{children:"get_score_streak_level()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_score_streak_level(player_index: int): int\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns a number between 0 and 3. 0 is the lowest score streak (no pointonium is given), while 3 is the highest (3 pointoniums is usually given)"}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"stop_game",children:(0,t.jsx)(n.code,{children:"stop_game()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.stop_game()\n"})}),"\n",(0,t.jsx)(n.p,{children:"Ends the current game."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_player_inputs",children:(0,t.jsx)(n.code,{children:"get_player_inputs()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_player_inputs(player_index: int): FixedPoint, FixedPoint, FixedPoint, FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the inputs of the player at the specified ",(0,t.jsx)(n.code,{children:"index"}),". The return values are in order: the movement joystick's angle (between 0 and 2pi), the movement joystick's distance (between 0 and 1), the shoot joystick's angle (between 0 and 2pi), and the shoot joystick's distance (between 0 and 1)."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local move_angle, move_distance, shoot_angle, shoot_distance = pewpew.get_player_inputs(0)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_score_of_player",children:(0,t.jsx)(n.code,{children:"get_score_of_player()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_score_of_player(player_index: int): int\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the score of the player at the specified ",(0,t.jsx)(n.code,{children:"player_index"}),". ",(0,t.jsx)(n.code,{children:"player_index"})," must in the range [0, get_number_of_players() - 1]."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"configure_player",children:(0,t.jsx)(n.code,{children:"configure_player()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.configure_player(\n player_index: int,\n configuration: table {\n has_lost: bool,\n shield: int,\n camera_x_override: FixedPoint,\n camera_y_override: FixedPoint,\n camera_distance: FixedPoint,\n camera_rotation_x_axis: FixedPoint,\n move_joystick_color: int,\n shoot_joystick_color: int\n }\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Configures the player at the specified ",(0,t.jsx)(n.code,{children:"player_index"}),". ",(0,t.jsx)(n.code,{children:"player_index"})," must in the range [0, get_number_of_players() - 1]. A ",(0,t.jsx)(n.code,{children:"camera_distance"})," less than 0fx makes the camera move away from the ship. ",(0,t.jsx)(n.code,{children:"camera_rotation_x_axis"})," is in radian and rotates along the X axis.\nTo temporarily override the XY position of the camera, set ",(0,t.jsx)(n.strong,{children:"both"})," ",(0,t.jsx)(n.code,{children:"camera_x_override"})," and ",(0,t.jsx)(n.code,{children:"camera_y_override"}),"; this will make the camera be interpolated from wherever it was, to that new position."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"pewpew.configure_player(0, {shield = 3, camera_distance = 50fx, move_joystick_color = 0xffff00ff})\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"configure_player_hud",children:(0,t.jsx)(n.code,{children:"configure_player_hud()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.configure_player_hud(\n player_index: int,\n configuration: table {\n top_left_line: string\n }\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Configures the player's HUD.",(0,t.jsx)(n.code,{children:"player_index"})," must in the range [0, get_number_of_players() - 1]."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'pewpew.configure_player_hud(0, {top_left_line = "Hello World"})\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_player_configuration",children:(0,t.jsx)(n.code,{children:"get_player_configuration()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_player_configuration(player_index: int): table {\n shield: int,\n has_lost: bool\n }\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns a map containing the configuration of the player at the specified ",(0,t.jsx)(n.code,{children:"player_index"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local shield = pewpew.get_player_configuration(0).shield\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"configure_player_ship_weapon",children:(0,t.jsx)(n.code,{children:"configure_player_ship_weapon()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.configure_player_ship_weapon(\n ship_id: EntityId,\n configuration: table {\n frequency: int,\n cannon: int,\n duration: int\n }\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Configures the weapon of the ship identified with ",(0,t.jsx)(n.code,{children:"ship_id"})," using ",(0,t.jsx)(n.code,{children:"configuration"}),". ",(0,t.jsx)(n.code,{children:"frequency"})," determines the frequency of the shots. ",(0,t.jsx)(n.code,{children:"cannon"})," determines the type of cannon. ",(0,t.jsx)(n.code,{children:"duration"})," determines the number of game ticks during which the weapon will be available. Once the duration expires, the weapon reverts to its permanent configuration. If ",(0,t.jsx)(n.code,{children:"duration"})," is omitted, the weapon will be permanently set to this configuration. If ",(0,t.jsx)(n.code,{children:"frequency"})," or ",(0,t.jsx)(n.code,{children:"cannon"})," is omitted, the ship is configured to not have any weapon."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local weapon_config = {frequency = pewpew.CannonFrequency.FREQ_10, cannon = pewpew.CannonType.DOUBLE}\nlocal ship_id = player_helpers.new_player_ship(100fx, 200fx, 0)\npewpew.configure_player_ship_weapon(ship_id, weapon_config)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"add_damage_to_player_ship",children:(0,t.jsx)(n.code,{children:"add_damage_to_player_ship()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.add_damage_to_player_ship(\n ship_id: EntityId,\n damage: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Reduces the amount of shield of the player that owns the ship by ",(0,t.jsx)(n.code,{children:"damage"})," points. If the player receives damage while having 0 shields left, the player loses."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"add_arrow_to_player_ship",children:(0,t.jsx)(n.code,{children:"add_arrow_to_player_ship()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.add_arrow_to_player_ship(\n ship_id: EntityId,\n target_id: EntityId,\n color: int\n): int\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Adds an arrow to the ship identified with ",(0,t.jsx)(n.code,{children:"ship_id"})," pointing towards the entity identified with ",(0,t.jsx)(n.code,{children:"entity_id"}),", and returns the identifier of the arrow. ",(0,t.jsx)(n.code,{children:"color"})," specifies the arrow's color. The arrow is automatically removed when the target entity is destroyed."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"remove_arrow_from_player_ship",children:(0,t.jsx)(n.code,{children:"remove_arrow_from_player_ship()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.remove_arrow_from_player_ship(\n ship_id: EntityId,\n arrow_id: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Removes the arrow identified by ",(0,t.jsx)(n.code,{children:"arrow_id"})," from the ship identified by ",(0,t.jsx)(n.code,{children:"ship_id"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"make_player_ship_transparent",children:(0,t.jsx)(n.code,{children:"make_player_ship_transparent()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.make_player_ship_transparent(\n ship_id: EntityId,\n transparency_duration: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Makes the player ship transparent for ",(0,t.jsx)(n.code,{children:"transparency_duration"})," game ticks."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"set_player_ship_speed",children:(0,t.jsx)(n.code,{children:"set_player_ship_speed()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.set_player_ship_speed(\n ship_id: EntityId,\n factor: FixedPoint,\n offset: FixedPoint,\n duration: int\n): FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets and returns the ",(0,t.jsx)(n.strong,{children:"effective speed"})," of the specified player ship as a function of the ",(0,t.jsx)(n.strong,{children:"base speed"})," of the ship. By default, a player ship moves according to its base speed, which is 10 distance units per tick (in the future, different ships may have different base speeds).\nAssuming the base speed of the ship is S, the new effective speed will be ",(0,t.jsx)(n.code,{children:"(factor*S)+offset"}),". ",(0,t.jsx)(n.code,{children:"duration"})," is the number of ticks during which the effective speed will be applied. Afterwards, the ship's speed reverts to its base speed. If ",(0,t.jsx)(n.code,{children:"duration"})," is negative, the effective speed never reverts to the base speed."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_all_entities",children:(0,t.jsx)(n.code,{children:"get_all_entities()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_all_entities(): List\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the list of the entityIDs of all the entities currently in the level. This includes the various bullets and ",(0,t.jsx)(n.em,{children:"all"})," the custom entities."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'local entities = pewpew.get_all_entities()\npewpew.print("There are " .. #entities .. " entities in the level")\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_entities_colliding_with_disk",children:(0,t.jsx)(n.code,{children:"get_entities_colliding_with_disk()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_entities_colliding_with_disk(\n center_x: FixedPoint,\n center_y: FixedPoint,\n radius: FixedPoint\n): List\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns the list of collidable entities (which includes all enemies) that overlap with the given disk."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local entities = pewpew.get_entities_colliding_with_disk(100fx, 100fx, 30fx)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_entity_count",children:(0,t.jsx)(n.code,{children:"get_entity_count()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_entity_count(type: int): int\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the number of entities of type ",(0,t.jsx)(n.code,{children:"type"})," that are alive."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local number_of_bafs = pewpew.get_entity_count(pewpew.EntityType.BAF)\nlocal number_of_asteroids = pewpew.get_entity_count(pewpew.EntityType.ASTEROID)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"get_entity_type",children:(0,t.jsx)(n.code,{children:"get_entity_type()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.get_entity_type(entity_id: EntityId): int\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns the type of the given entity."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'local type = pewpew.get_entity_type(id)\nif type == pewpew.EntityType.BAF then\n pewpew.print("the entity is a BAF")\nend\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"play_ambient_sound",children:(0,t.jsx)(n.code,{children:"play_ambient_sound()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.play_ambient_sound(\n sound_path: string,\n index: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Plays the sound described at ",(0,t.jsx)(n.code,{children:"sound_path"})," at the index ",(0,t.jsx)(n.code,{children:"index"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'pewpew.play_ambient_sound("/dynamic/my_custom_sound.lua", 0)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"play_sound",children:(0,t.jsx)(n.code,{children:"play_sound()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.play_sound(\n sound_path: string,\n index: int,\n x: FixedPoint,\n y: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Plays the sound described at ",(0,t.jsx)(n.code,{children:"sound_path"})," at the in-game location of ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'pewpew.play_sound("/dynamic/my_custom_sound.lua", 0, 100fx, 100fx)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"create_explosion",children:(0,t.jsx)(n.code,{children:"create_explosion()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.create_explosion(\n x: FixedPoint,\n y: FixedPoint,\n color: int,\n scale: FixedPoint,\n particle_count: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates an explosion of particles at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),". ",(0,t.jsx)(n.code,{children:"color"})," specifies the color of the explosion. ",(0,t.jsx)(n.code,{children:"scale"})," describes how large the explosion will be. It should be in the range ]0, 10], with 1 being an average explosion. ",(0,t.jsx)(n.code,{children:"particle_count"})," specifies the number of particles that make up the explosion. It must be in the range [1, 100]."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"pewpew.create_explosion(200fx, 100fx, 0xffffffff, 1fx, 20) -- medium explosion\npewpew.create_explosion(300fx, 100fx, 0xffffffff, 3fx, 50) -- large red explosion\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_asteroid",children:(0,t.jsx)(n.code,{children:"new_asteroid()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_asteroid(\n x: FixedPoint,\n y: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Asteroid at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"})," and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_asteroid_with_size",children:(0,t.jsx)(n.code,{children:"new_asteroid_with_size()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_asteroid_with_size(\n x: FixedPoint,\n y: FixedPoint,\n size: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Asteroid at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"})," with an AsteroidSize given by ",(0,t.jsx)(n.code,{children:"size"})," and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_baf",children:(0,t.jsx)(n.code,{children:"new_baf()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_baf(\n x: FixedPoint,\n y: FixedPoint,\n angle: FixedPoint,\n speed: FixedPoint,\n lifetime: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new BAF at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId. ",(0,t.jsx)(n.code,{children:"angle"})," specifies the angle at which the BAF will move. ",(0,t.jsx)(n.code,{children:"speed"})," specifies the maximum speed it will reach. ",(0,t.jsx)(n.code,{children:"lifetime"})," indicates the number of game ticks after which the BAF is destroyed the next time it hits a wall. Specify a negative ",(0,t.jsx)(n.code,{children:"lifetime"})," to create a BAF that lives forever."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_baf_red",children:(0,t.jsx)(n.code,{children:"new_baf_red()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_baf_red(\n x: FixedPoint,\n y: FixedPoint,\n angle: FixedPoint,\n speed: FixedPoint,\n lifetime: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new red BAF at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId. A red BAF has more health points than a regular BAF. ",(0,t.jsx)(n.code,{children:"angle"})," specifies the angle at which the BAF will move. ",(0,t.jsx)(n.code,{children:"speed"})," specifies the maximum speed it will reach. ",(0,t.jsx)(n.code,{children:"lifetime"})," indicates the number of game ticks after which the BAF is destroyed the next time it hits a wall. Specify a negative ",(0,t.jsx)(n.code,{children:"lifetime"})," to create a BAF that lives forever."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_baf_blue",children:(0,t.jsx)(n.code,{children:"new_baf_blue()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_baf_blue(\n x: FixedPoint,\n y: FixedPoint,\n angle: FixedPoint,\n speed: FixedPoint,\n lifetime: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new blue BAF at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId. A blue BAF bounces on walls with a slightly randomized angle. ",(0,t.jsx)(n.code,{children:"angle"})," specifies the angle at which the BAF will move. ",(0,t.jsx)(n.code,{children:"speed"})," specifies the maximum speed it will reach. ",(0,t.jsx)(n.code,{children:"lifetime"})," indicates the number of game ticks after which the BAF is destroyed the next time it hits a wall. Specify a negative ",(0,t.jsx)(n.code,{children:"lifetime"})," to create a BAF that lives forever."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_bomb",children:(0,t.jsx)(n.code,{children:"new_bomb()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_bomb(\n x: FixedPoint,\n y: FixedPoint,\n type: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Bomb at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"pewpew.new_bomb(10fx, 10fx, pewpew.BombType.SMALL_ATOMIZE)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_bonus",children:(0,t.jsx)(n.code,{children:"new_bonus()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_bonus(\n x: FixedPoint,\n y: FixedPoint,\n type: int,\n config: table {\n box_duration: int,\n cannon: int,\n frequency: int,\n weapon_duration: int,\n number_of_shields: int,\n speed_factor: FixedPoint,\n speed_offset: FixedPoint,\n speed_duration: int,\n taken_callback: function\n }\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Bonus at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"})," of the type ",(0,t.jsx)(n.code,{children:"type"}),", and returns its entityId.\nFor shield bonuses, the option ",(0,t.jsx)(n.code,{children:"number_of_shields"})," determines how many shields are given out.\nFor weapon bonuses, the options ",(0,t.jsx)(n.code,{children:"cannon"}),", ",(0,t.jsx)(n.code,{children:"frequency"}),", ",(0,t.jsx)(n.code,{children:"weapon_duration"})," have the same meaning as in ",(0,t.jsx)(n.code,{children:"pewpew.configure_player_ship_weapon"}),".\nFor speed bonuses, the options ",(0,t.jsx)(n.code,{children:"speed_factor"}),", ",(0,t.jsx)(n.code,{children:"speed_offset"}),",and ",(0,t.jsx)(n.code,{children:"speed_duration"})," have the same meaning as in ",(0,t.jsx)(n.code,{children:"set_player_speed"}),". ",(0,t.jsx)(n.code,{children:"taken_callback"})," is called when the bonus is taken, and is mandatory for the reinstantiation bonus. The callback receives as arguments the entity id of the bonus, the player id, and the ship's entity id.\nThe default box duration is 400 ticks."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"pewpew.new_bonus(10fx, 10fx, pewpew.BonusType.WEAPON, {cannon = pewpew.CannonType.TIC_TOC, frequency = pewpew.CannonFrequency.FREQ_5, weapon_duration = 100})\npewpew.new_bonus(10fx, 10fx, pewpew.BonusType.SHIELD, {number_of_shields = 3})\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_crowder",children:(0,t.jsx)(n.code,{children:"new_crowder()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_crowder(\n x: FixedPoint,\n y: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Crowder at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_floating_message",children:(0,t.jsx)(n.code,{children:"new_floating_message()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_floating_message(\n x: FixedPoint,\n y: FixedPoint,\n str: string,\n config: table {\n scale: FixedPoint,\n ticks_before_fade: int,\n is_optional: bool\n }\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new floating message at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", with ",(0,t.jsx)(n.code,{children:"str"})," as the message. The scale is a number that determines how large the message will be. ",(0,t.jsx)(n.code,{children:"1"})," is the default scale. ",(0,t.jsx)(n.code,{children:"ticks_before_fade"})," determines how many ticks occur before the message starts to fade out. ",(0,t.jsx)(n.code,{children:"is_optional"})," can be used to tell the game if the message can be hidden depending on the user's UI settings.\nIf not specified, ",(0,t.jsx)(n.code,{children:"scale"})," is 1, ",(0,t.jsx)(n.code,{children:"ticks_before_fade"})," is 30 and ",(0,t.jsx)(n.code,{children:"is_optional"})," is ",(0,t.jsx)(n.code,{children:"false"}),".\nReturns the floating message's entityId."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'pewpew.new_floating_message(10fx, 10fx, "hello", {scale = 2fx, ticks_before_fade = 60, is_optional = true})\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_customizable_entity",children:(0,t.jsx)(n.code,{children:"new_customizable_entity()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_customizable_entity(\n x: FixedPoint,\n y: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new customizable entity at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_inertiac",children:(0,t.jsx)(n.code,{children:"new_inertiac()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_inertiac(\n x: FixedPoint,\n y: FixedPoint,\n acceleration: FixedPoint,\n angle: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Inertiac at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId. The inertiac will accelerate according to ",(0,t.jsx)(n.code,{children:"acceleration"}),". It spawns with a random velocity in a direction specified by ",(0,t.jsx)(n.code,{children:"angle"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_mothership",children:(0,t.jsx)(n.code,{children:"new_mothership()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_mothership(\n x: FixedPoint,\n y: FixedPoint,\n type: int,\n angle: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Mothership at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"pewpew.new_mothership(50fx, 50fx, pewpew.MothershipType.THREE_CORNERS, fmath.tau() / 4fx)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_pointonium",children:(0,t.jsx)(n.code,{children:"new_pointonium()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_pointonium(\n x: FixedPoint,\n y: FixedPoint,\n value: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Pointonium at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),". Value must be 64, 128, or 256."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_player_ship",children:(0,t.jsx)(n.code,{children:"new_player_ship()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_player_ship(\n x: FixedPoint,\n y: FixedPoint,\n player_index: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Player Ship at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"})," for the player identified by ",(0,t.jsx)(n.code,{children:"player_index"}),", and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_player_bullet",children:(0,t.jsx)(n.code,{children:"new_player_bullet()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_player_bullet(\n x: FixedPoint,\n y: FixedPoint,\n angle: FixedPoint,\n player_index: int\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new bullet at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"})," with the angle ",(0,t.jsx)(n.code,{children:"angle"})," belonging to the player at the index ",(0,t.jsx)(n.code,{children:"player_index"}),". Returns the entityId of the bullet."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_rolling_cube",children:(0,t.jsx)(n.code,{children:"new_rolling_cube()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_rolling_cube(\n x: FixedPoint,\n y: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Rolling Cube at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_rolling_sphere",children:(0,t.jsx)(n.code,{children:"new_rolling_sphere()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_rolling_sphere(\n x: FixedPoint,\n y: FixedPoint,\n angle: FixedPoint,\n speed: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Rolling Sphere at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),", and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_wary",children:(0,t.jsx)(n.code,{children:"new_wary()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_wary(\n x: FixedPoint,\n y: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new Wary at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"new_ufo",children:(0,t.jsx)(n.code,{children:"new_ufo()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.new_ufo(\n x: FixedPoint,\n y: FixedPoint,\n dx: FixedPoint\n): EntityId\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Creates a new UFO at the location ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"})," moving horizontally at the speed of ",(0,t.jsx)(n.code,{children:"dx"}),", and returns its entityId."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"rolling_cube_set_enable_collisions_with_walls",children:(0,t.jsx)(n.code,{children:"rolling_cube_set_enable_collisions_with_walls()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.rolling_cube_set_enable_collisions_with_walls(\n entity_id: EntityId,\n collide_with_walls: bool\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets whether the rolling cube identified with ",(0,t.jsx)(n.code,{children:"id"})," collides with walls. By default it does not."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local x,y = pewpew.rolling_cube_set_enable_collisions_with_walls(id, true)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"ufo_set_enable_collisions_with_walls",children:(0,t.jsx)(n.code,{children:"ufo_set_enable_collisions_with_walls()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.ufo_set_enable_collisions_with_walls(\n entity_id: EntityId,\n collide_with_walls: bool\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets whether the ufo identified with ",(0,t.jsx)(n.code,{children:"id"})," collides with walls. By default it does not."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local x,y = pewpew.ufo_set_enable_collisions_with_walls(id, true)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_get_position",children:(0,t.jsx)(n.code,{children:"entity_get_position()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_get_position(entity_id: EntityId): FixedPoint, FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the position of the entity identified by ",(0,t.jsx)(n.code,{children:"id"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local x,y = pewpew.entity_get_position(entity_id)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_get_is_alive",children:(0,t.jsx)(n.code,{children:"entity_get_is_alive()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_get_is_alive(entity_id: EntityId): bool\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns whether the entity identified by ",(0,t.jsx)(n.code,{children:"id"})," is alive or not."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_get_is_started_to_be_destroyed",children:(0,t.jsx)(n.code,{children:"entity_get_is_started_to_be_destroyed()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_get_is_started_to_be_destroyed(entity_id: EntityId): bool\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns whether the entity identified by ",(0,t.jsx)(n.code,{children:"id"})," is in the process of being destroyed. Returns false if the entity does not exist."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_set_position",children:(0,t.jsx)(n.code,{children:"entity_set_position()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_set_position(\n entity_id: EntityId,\n x: FixedPoint,\n y: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the position of the entity identified by ",(0,t.jsx)(n.code,{children:"id"})," to ",(0,t.jsx)(n.code,{children:"x"}),",",(0,t.jsx)(n.code,{children:"y"})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_set_radius",children:(0,t.jsx)(n.code,{children:"entity_set_radius()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_set_radius(\n entity_id: EntityId,\n radius: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the radius of the entity identified by ",(0,t.jsx)(n.code,{children:"id"}),". To give you a sense of scale, motherships have a radius of 28fx."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_set_update_callback",children:(0,t.jsx)(n.code,{children:"entity_set_update_callback()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_set_update_callback(\n entity_id: EntityId,\n callback: function\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets a callback that will be called at every tick as long as the entity identified by ",(0,t.jsx)(n.code,{children:"id"})," is alive. Remove the callback by passing a nil ",(0,t.jsx)(n.code,{children:"callback"}),". The callbacks gets called with the entity ID."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"local function my_update_callback(entity_id)\n local x,y = pewpew.entity_get_position(entity_id)\n pewpew.entity_set_position(entity_id, x + 2fx, y) -- move the entity to the right\nend\npewpew.entity_set_update_callback(entity_id, my_update_callback)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_destroy",children:(0,t.jsx)(n.code,{children:"entity_destroy()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_destroy(entity_id: EntityId)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Makes the entity identified by ",(0,t.jsx)(n.code,{children:"id"})," immediately disappear forever."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"entity_react_to_weapon",children:(0,t.jsx)(n.code,{children:"entity_react_to_weapon()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.entity_react_to_weapon(\n entity_id: EntityId,\n weapon: table {\n type: int,\n x: FixedPoint,\n y: FixedPoint,\n player_index: int\n }\n): bool\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Makes the entity identified by ",(0,t.jsx)(n.code,{children:"id"})," react to the weapon described in ",(0,t.jsx)(n.code,{children:"weapon_description"}),". Returns whether the entity reacted to the weapon. The returned value is typically used to decide whether the weapon should continue to exist or not. In the case of an explosion, ",(0,t.jsx)(n.code,{children:"x"})," and ",(0,t.jsx)(n.code,{children:"y"})," should store the origin of the explosion. In the case of a bullet, ",(0,t.jsx)(n.code,{children:"x"})," and ",(0,t.jsx)(n.code,{children:"y"})," should store the vector of the bullet. The player identified by ",(0,t.jsx)(n.code,{children:"player_index"})," will be assigned points. If ",(0,t.jsx)(n.code,{children:"player_index"})," is invalid, no player will be assigned points."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_position_interpolation",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_position_interpolation()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_position_interpolation(\n entity_id: EntityId,\n enable: bool\n)\n"})}),"\n",(0,t.jsx)(n.p,{children:"Sets whether the position of the mesh wil be interpolated when rendering. In general, this should be set to true if the entity will be moving smoothly."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_mesh",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_mesh(\n entity_id: EntityId,\n file_path: string,\n index: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"})," to the mesh described in the file ",(0,t.jsx)(n.code,{children:"file_path"})," at the index ",(0,t.jsx)(n.code,{children:"index"}),". ",(0,t.jsx)(n.code,{children:"index"})," starts at 0. If ",(0,t.jsx)(n.code,{children:"file_path"})," is an empty string, the mesh is removed."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'local id = pewpew.new_customizable_entity(0fx, 0fx)\npewpew.customizable_entity_set_mesh(id, "/dynamic/graphics.lua", 0)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_flipping_meshes",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_flipping_meshes()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_flipping_meshes(\n entity_id: EntityId,\n file_path: string,\n index_0: int,\n index_1: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Similar to ",(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh"}),", but sets two meshes that will be used in alternation. By specifying 2 separate meshes, 60 fps animations can be achieved."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'local id = pewpew.new_customizable_entity(0fx, 0fx)\npewpew.customizable_entity_set_flipping_meshes(id, "/dynamic/graphics.lua", 0, 1)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_mesh_color",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh_color()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_mesh_color(\n entity_id: EntityId,\n color: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the color multiplier for the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_string",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_string()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_string(\n entity_id: EntityId,\n text: string\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the string to be displayed as part of the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_mesh_xyz",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh_xyz()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_mesh_xyz(\n entity_id: EntityId,\n x: FixedPoint,\n y: FixedPoint,\n z: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the position of the mesh to x,y,z, relative to the center ofthe customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"})]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_mesh_z",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh_z()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_mesh_z(\n entity_id: EntityId,\n z: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the height of the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"}),". A ",(0,t.jsx)(n.code,{children:"z"})," greater to 0 makes the mesh be closer, while a ",(0,t.jsx)(n.code,{children:"z"})," less than 0 makes the mesh be further away."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_mesh_scale",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh_scale()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_mesh_scale(\n entity_id: EntityId,\n scale: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the scale of the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"}),". A ",(0,t.jsx)(n.code,{children:"scale"})," less than 1 makes the mesh appear smaller, while a ",(0,t.jsx)(n.code,{children:"scale"})," greater than 1 makes the mesh appear larger."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_mesh_xyz_scale",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh_xyz_scale()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_mesh_xyz_scale(\n entity_id: EntityId,\n x_scale: FixedPoint,\n y_scale: FixedPoint,\n z_scale: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the scale of the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"})," along the x,y,z axis. A ",(0,t.jsx)(n.code,{children:"scale"})," less than 1 makes the mesh appear smaller, while a ",(0,t.jsx)(n.code,{children:"scale"})," greater than 1 makes the mesh appear larger."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_mesh_angle",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_mesh_angle()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_mesh_angle(\n entity_id: EntityId,\n angle: FixedPoint,\n x_axis: FixedPoint,\n y_axis: FixedPoint,\n z_axis: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the rotation angle of the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"}),". The rotation is applied along the axis defined by ",(0,t.jsx)(n.code,{children:"x_axis"}),",",(0,t.jsx)(n.code,{children:"y_axis"}),",",(0,t.jsx)(n.code,{children:"z_axis"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"-- Rotate the entity by 45 degrees along the z_axis\npewpew.customizable_entity_set_mesh_angle(entity_id, fmath.tau() / 8fx, 0fx, 0fx, 1fx)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_skip_mesh_attributes_interpolation",children:(0,t.jsx)(n.code,{children:"customizable_entity_skip_mesh_attributes_interpolation()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_skip_mesh_attributes_interpolation(entity_id: EntityId)\n"})}),"\n",(0,t.jsx)(n.p,{children:"Skips the interpolation of the mesh's attributes (x, y, z, scale_x, scale_y, scale_z, rotation)."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_configure_music_response",children:(0,t.jsx)(n.code,{children:"customizable_entity_configure_music_response()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_configure_music_response(\n entity_id: EntityId,\n config: table {\n color_start: int,\n color_end: int,\n scale_x_start: FixedPoint,\n scale_x_end: FixedPoint,\n scale_y_start: FixedPoint,\n scale_y_end: FixedPoint,\n scale_z_start: FixedPoint,\n scale_z_end: FixedPoint\n }\n)\n"})}),"\n",(0,t.jsx)(n.p,{children:"Configures the way the entity is going to respond to the music."}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:" -- Makes the entity larger\n pewpew.customizable_entity_configure_music_response(entity_id, {scale_x_start = 1fx, scale_x_end = 2fx})\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_add_rotation_to_mesh",children:(0,t.jsx)(n.code,{children:"customizable_entity_add_rotation_to_mesh()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_add_rotation_to_mesh(\n entity_id: EntityId,\n angle: FixedPoint,\n x_axis: FixedPoint,\n y_axis: FixedPoint,\n z_axis: FixedPoint\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Adds a rotation to the mesh of the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"}),". The rotation is applied along the axis defined by ",(0,t.jsx)(n.code,{children:"x_axis"}),",",(0,t.jsx)(n.code,{children:"y_axis"}),",",(0,t.jsx)(n.code,{children:"z_axis"}),"."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:"-- Rotate the entity by 45 degrees along the z_axis\npewpew.customizable_entity_add_rotation_to_mesh(entity_id, fmath.tau() / 8fx, 0fx, 0fx, 1fx)\n"})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_visibility_radius",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_visibility_radius()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_visibility_radius(\n entity_id: EntityId,\n radius: FixedPoint\n)\n"})}),"\n",(0,t.jsx)(n.p,{children:"Sets the radius defining the visibility of the entity. This allows the game to know when an entity is actually visible, which in turns allows to massively optimize the rendering. Use the smallest value possible. If not set, the rendering radius is an unspecified large number that effectively makes the entity always be rendered, even if not visible."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_configure_wall_collision",children:(0,t.jsx)(n.code,{children:"customizable_entity_configure_wall_collision()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_configure_wall_collision(\n entity_id: EntityId,\n collide_with_walls: bool,\n collision_callback: function\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"collide_with_walls"})," configures whether the entity should stop when colliding with walls. If ",(0,t.jsx)(n.code,{children:"collision_callback"})," is not nil, it is called anytime a collision is detected. The callback gets called with the entity id of the entity withthe callback, and with the normal to the wall."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'function my_wall_collision_callback(entity_id, wall_normal_x, wall_normal_y)\n pewpew.print("A wall collision happened with entity " .. entity_id)\nend\nlocal id = pewpew.new_customizable_entity(100fx, 100fx)\npewpew.customizable_entity_configure_wall_collision(id, my_wall_collision_callback)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_player_collision_callback",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_player_collision_callback()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_player_collision_callback(\n entity_id: EntityId,\n collision_callback: function\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the callback for when the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"})," collides with a player's ship. The callback gets called with the entity id of the entity with the callback, and the player_index and ship_id that were involved in the collision. Don't forget to set a radius on the customizable entity, otherwise no collisions will be detected."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'function my_collision_callback(entity_id, player_index, ship_entity_id)\n pewpew.print("The entity: " .. entity_id)\n pewpew.print("Collided with the ship: " .. ship_entity_id)\n pewpew.print("That belongs to the player: " .. player_index)\nend\nlocal id = pewpew.new_customizable_entity(100fx, 100fx)\npewpew.customizable_entity_set_player_collision_callback(id, my_collision_callback)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_set_weapon_collision_callback",children:(0,t.jsx)(n.code,{children:"customizable_entity_set_weapon_collision_callback()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_set_weapon_collision_callback(\n entity_id: EntityId,\n weapon_collision_callback: function\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Sets the callback for when the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"})," collides with a player's weapon. The callback gets called with the entity_id of the entity on which the callback is set, the player_index of the player that triggered the weapon, and the type of the weapon. The callback ",(0,t.jsx)(n.em,{children:"must"})," return a boolean saying whether the entity reacts to the weapon. In the case of a bullet, this boolean determines whether the bullet should be destroyed."]}),"\n",(0,t.jsxs)(n.blockquote,{children:["\n",(0,t.jsx)(n.p,{children:"Example:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-lua",children:'local id = pewpew.new_customizable_entity(100fx, 100fx)\npewpew.customizable_entity_set_weapon_collision_callback(id, function(entity_id, player_index, weapon_type)\n pewpew.print("Collided with weapon from player: " .. player_index)\n if weapon_type == pewpew.WeaponType.BULLET then\n pewpew.print("Collided with bullet!")\n end\n return true\nend)\n'})}),"\n"]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_start_spawning",children:(0,t.jsx)(n.code,{children:"customizable_entity_start_spawning()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_start_spawning(\n entity_id: EntityId,\n spawning_duration: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Makes the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"})," spawn for a duration of ",(0,t.jsx)(n.code,{children:"spawning_duration"})," game ticks."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"customizable_entity_start_exploding",children:(0,t.jsx)(n.code,{children:"customizable_entity_start_exploding()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"pewpew.customizable_entity_start_exploding(\n entity_id: EntityId,\n explosion_duration: int\n)\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Makes the customizable entity identified by ",(0,t.jsx)(n.code,{children:"id"})," explode for a duration of ",(0,t.jsx)(n.code,{children:"explosion_duration"})," game ticks. After the explosion, the entity is destroyed. ",(0,t.jsx)(n.code,{children:"explosion_duration"})," must be less than 255. Any scale applied to the entity is also applied to the explosion."]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(r,{...e})}):r(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>d,x:()=>c});var t=i(6540);const s={},l=t.createContext(s);function d(e){const n=t.useContext(l);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function c(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:d(e.components),t.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/46e25335.77249d93.js b/assets/js/46e25335.77249d93.js new file mode 100644 index 0000000..e6eb0ef --- /dev/null +++ b/assets/js/46e25335.77249d93.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[9612],{4212:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>r,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>d});var s=i(4848),t=i(8453);const o={sidebar_position:1},r="Manifest files",l={id:"File Information/manifest-files",title:"Manifest files",description:"Manifests are written in JSON.",source:"@site/docs/File Information/manifest-files.md",sourceDirName:"File Information",slug:"/File Information/manifest-files",permalink:"/ppl-docs/docs/File Information/manifest-files",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/File Information/manifest-files.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Standard libraries",permalink:"/ppl-docs/docs/APIs/standard-libraries"},next:{title:"Mesh files",permalink:"/ppl-docs/docs/File Information/mesh-files"}},a={},d=[{value:"Manifest fields",id:"manifest-fields",level:2}];function c(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"manifest-files",children:"Manifest files"}),"\n",(0,s.jsx)(n.p,{children:"Manifests are written in JSON.\nExample of a manifest file:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-json",metastring:'title="manifest.json"',children:'{\n "name": "The name of the level",\n "descriptions": ["A short description for your level."],\n "information": "Information regarding your level. Up to 350 characters long. Can include #ff0000ffcolor!",\n "entry_point": "level.lua",\n "has_score_leaderboard": true,\n "rank_thresholds_1p": { "bronze": 1000, "silver": 2000, "gold": 3000 }\n}\n'})}),"\n",(0,s.jsx)(n.h2,{id:"manifest-fields",children:"Manifest fields"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"name"})," is the name of the level. Keep it short (30 char max)."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"descriptions"})," is an array of strings. You can put multiple descriptions, but for now only the first string is displayed anywhere."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"information"})," is an optional string that can be 350 characters long that should contain information relevant to the level."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"entry_point"})," contains the path to the main entry point of the level."]}),"\n"]}),"\n",(0,s.jsx)(n.admonition,{type:"warning",children:(0,s.jsxs)(n.p,{children:[(0,s.jsx)(n.code,{children:"entry_point"})," must be ",(0,s.jsx)(n.code,{children:"level.lua"}),"."]})}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"has_score_leaderboard"})," is a boolean that specifies whether the level should have a score leaderboard."]}),"\n",(0,s.jsxs)(n.li,{children:[(0,s.jsx)(n.code,{children:"rank_thresholds_1p"})," contains the requirements for the players to unlock bronze, silver, and gold stars. You must not include this field if ",(0,s.jsx)(n.code,{children:"has_score_leaderboard"})," is false. If all the thresholds are 0, then the level will not give out stars."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(c,{...e})}):c(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>l});var s=i(6540);const t={},o=s.createContext(t);function r(e){const n=s.useContext(o);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:r(e.components),s.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/46e25335.d83f8ae7.js b/assets/js/46e25335.d83f8ae7.js deleted file mode 100644 index e52c912..0000000 --- a/assets/js/46e25335.d83f8ae7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[9612],{4212:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>l,toc:()=>d});var t=i(4848),s=i(8453);const r={sidebar_position:1},o="Manifest files",l={id:"File Information/manifest-files",title:"Manifest files",description:"Manifests are written in JSON.",source:"@site/docs/File Information/manifest-files.md",sourceDirName:"File Information",slug:"/File Information/manifest-files",permalink:"/docs/File Information/manifest-files",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/File Information/manifest-files.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Standard libraries",permalink:"/docs/APIs/standard-libraries"},next:{title:"Mesh files",permalink:"/docs/File Information/mesh-files"}},a={},d=[{value:"Manifest fields",id:"manifest-fields",level:2}];function c(e){const n={admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,s.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"manifest-files",children:"Manifest files"}),"\n",(0,t.jsx)(n.p,{children:"Manifests are written in JSON.\nExample of a manifest file:"}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-json",metastring:'title="manifest.json"',children:'{\n "name": "The name of the level",\n "descriptions": ["A short description for your level."],\n "information": "Information regarding your level. Up to 350 characters long. Can include #ff0000ffcolor!",\n "entry_point": "level.lua",\n "has_score_leaderboard": true,\n "rank_thresholds_1p": { "bronze": 1000, "silver": 2000, "gold": 3000 }\n}\n'})}),"\n",(0,t.jsx)(n.h2,{id:"manifest-fields",children:"Manifest fields"}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"name"})," is the name of the level. Keep it short (30 char max)."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"descriptions"})," is an array of strings. You can put multiple descriptions, but for now only the first string is displayed anywhere."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"information"})," is an optional string that can be 350 characters long that should contain information relevant to the level."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"entry_point"})," contains the path to the main entry point of the level."]}),"\n"]}),"\n",(0,t.jsx)(n.admonition,{type:"warning",children:(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"entry_point"})," must be ",(0,t.jsx)(n.code,{children:"level.lua"}),"."]})}),"\n",(0,t.jsxs)(n.ul,{children:["\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"has_score_leaderboard"})," is a boolean that specifies whether the level should have a score leaderboard."]}),"\n",(0,t.jsxs)(n.li,{children:[(0,t.jsx)(n.code,{children:"rank_thresholds_1p"})," contains the requirements for the players to unlock bronze, silver, and gold stars. You must not include this field if ",(0,t.jsx)(n.code,{children:"has_score_leaderboard"})," is false. If all the thresholds are 0, then the level will not give out stars."]}),"\n"]})]})}function h(e={}){const{wrapper:n}={...(0,s.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(c,{...e})}):c(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>l});var t=i(6540);const s={},r=t.createContext(s);function o(e){const n=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),t.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/61036be0.b3bc9242.js b/assets/js/61036be0.b3bc9242.js deleted file mode 100644 index 30d93f1..0000000 --- a/assets/js/61036be0.b3bc9242.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[2256],{1869:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>t,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>a,toc:()=>d});var i=s(4848),r=s(8453);const l={sidebar_position:1},o="Beginner Lua Tutorial",a={id:"Guides/Lua/beginner",title:"Beginner Lua Tutorial",description:"https://repl.it/languages/lua can be used to try Lua in the browser.",source:"@site/docs/Guides/Lua/beginner.md",sourceDirName:"Guides/Lua",slug:"/Guides/Lua/beginner",permalink:"/docs/Guides/Lua/beginner",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/Guides/Lua/beginner.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Sound files",permalink:"/docs/File Information/sound-files"},next:{title:"Intermediate",permalink:"/docs/Guides/Lua/intermediate"}},t={},d=[{value:"PRINTING EXAMPLE",id:"printing-example",level:3},{value:"VARIABLES EXAMPLE",id:"variables-example",level:3},{value:"IF STATEMENT EXAMPLE",id:"if-statement-example",level:3},{value:"FOR LOOP EXAMPLE",id:"for-loop-example",level:3},{value:"NESTED FOR LOOP EXAMPLE",id:"nested-for-loop-example",level:3},{value:"WHILE LOOP EXAMPLE",id:"while-loop-example",level:3},{value:"BREAK LOOPS EXAMPLE",id:"break-loops-example",level:3},{value:"FUNCTIONS EXAMPLE",id:"functions-example",level:3},{value:"TABLES EXAMPLE",id:"tables-example",level:3},{value:"FOR I, V IN PAIRS LOOP EXAMPLE",id:"for-i-v-in-pairs-loop-example",level:3}];function c(e){const n={a:"a",code:"code",h1:"h1",h3:"h3",p:"p",pre:"pre",strong:"strong",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"beginner-lua-tutorial",children:"Beginner Lua Tutorial"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://repl.it/languages/lua",children:"https://repl.it/languages/lua"})," can be used to try Lua in the browser."]}),"\n",(0,i.jsx)(n.p,{children:"These examples are more for review, rather than learning! If you see something here that you don't understand, continue to watch Lua tutorials on youtube!"}),"\n",(0,i.jsx)(n.h3,{id:"printing-example",children:"PRINTING EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'print("Hello world!")\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"Hello World!"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"print(2+3)\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"5"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'print("2+3")\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"2+3"})]}),"\n",(0,i.jsxs)(n.p,{children:["Anything in quotation marks ",(0,i.jsx)(n.code,{children:'" "'})," or ",(0,i.jsx)(n.code,{children:"' '"})," is a string. Printing a string will output exactly what you type! Anything not inside of quotation marks are registered as numbers, variables, or mathematics!"]}),"\n",(0,i.jsx)(n.h3,{id:"variables-example",children:"VARIABLES EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"my_variable = 5\nprint(my_variable)\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"5"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"x = 2\ny = 10\nprint(x+y)\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"12"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'x = 2\ny = 10\nprint("x+y")\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"x+y"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'some_text = "this is cool"\nprint(some_text)\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"this is cool"})]}),"\n",(0,i.jsx)(n.p,{children:"Variables can be assigned practically any value! You can store them as numbers, strings, and more!"}),"\n",(0,i.jsx)(n.h3,{id:"if-statement-example",children:"IF STATEMENT EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'x = 6\nif x > 5 then\n print("Greater than 5!")\nend\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"Greater than 5!"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'a = true\nb = false\n\nif a then\n print("True")\nend\n\nif a and b then\n print("True")\nelse\n print("False")\nend\n\nif a or b then\n print("True")\nelse\n print("False")\nend\n\nif b then\n print("True")\nend\n'})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"True\nFalse\nTrue\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'x = 5\ny = 5\nif x == y then\n print("True")\nend\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"True"})]}),"\n",(0,i.jsx)(n.p,{children:'Variables can also be assigned boolean values, which are true and false! With "and" statements, both or all arguments need to be true to equal true in total! With "or" statements, only one needs to be true to equal true in total! Both or all need to be false to be false in total!'}),"\n",(0,i.jsx)(n.h3,{id:"for-loop-example",children:"FOR LOOP EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'for i = 1, 5 do\n print("Hello!")\nend\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The following output is repeated 5 times:\n",(0,i.jsx)(n.code,{children:"Hello!"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"for i = 1, 10 do\n print(i)\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"for i = 1, 10, 2 do\n print(i)\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"1\n3\n5\n7\n9\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"for i = 0, -10, -1 do\n print(i)\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"0\n-1\n-2\n-3\n-4\n-5\n-6\n-7\n-8\n-9\n-10\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'local loopcount = 25\nfor i = 1, loopcount do\n print("Loop!")\nend\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The following output is repeated 25 times:\n",(0,i.jsx)(n.code,{children:"Loop!"})]}),"\n",(0,i.jsx)(n.p,{children:'For loops are useful for running the same code multiple times! The first line of the for loop has the syntax for i = Index, End Value, Increments. You set i as your starting value, separate with a comma, set your end value, and you can optionally set your increment as your third value. Don\'t forget the "do"!'}),"\n",(0,i.jsx)(n.h3,{id:"nested-for-loop-example",children:"NESTED FOR LOOP EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'for i = 1, 5 do\n print("This is the outer loop!")\n for j = 1, 3 do\n print("This is the inner loop!")\n end\nend\n'})}),"\n",(0,i.jsx)(n.p,{children:"The following output is repeated 5 times:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"This is the outer loop!\nThis is the inner loop!\nThis is the inner loop!\nThis is the inner loop!\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'local swim_laps = 10\nlocal paddles = 5\nfor i = 1, swim_laps do\n print("Lap : "..i)\n for j = 1, paddles do\n print("Paddle : "..j)\n end\nend\n'})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"Lap : 1\nPaddle : 1\nPaddle : 2\n"})}),"\n",(0,i.jsx)(n.p,{children:"...etc."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'for i = 1, 5 do\n for i = 1, 2 do\n print("This is fine!")\n end\nend\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The following output is repeated 10 times:\n",(0,i.jsx)(n.code,{children:"This is fine!"})]}),"\n",(0,i.jsx)(n.p,{children:"You are allowed to put for loops inside of other for loops! In if you put a for loop that repeats 3 times inside of a for loop that repeats 5 times, that inner loop runs 15 times total! With for loops, you can use any variable as your index! And with nested for loops, it is good practice to use different variables, like using i and j instead of using i twice."}),"\n",(0,i.jsx)(n.h3,{id:"while-loop-example",children:"WHILE LOOP EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local x = 3\nwhile x > 0 do\n print(x)\n x = x - 1\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"3\n2\n1\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local x = 3\nlocal y = 4\nwhile x > 0 and y > 0 do\n print(x,y)\n x = x - 1\n y = y - 1\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"3 4\n2 3\n1 2\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'while true do\n print("Hello!")\nend\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The following output is repeated indefinitely:\n",(0,i.jsx)(n.code,{children:"Hello!"})]}),"\n",(0,i.jsx)(n.p,{children:"A while loop is very similar to a for loop, except you can think of it as an if statement and for loop combined! The while loop runs while the conditions are true. So for a while true do loop, the loop runs forever! Be careful when making a while true do loop!"}),"\n",(0,i.jsx)(n.h3,{id:"break-loops-example",children:"BREAK LOOPS EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'while true do\n print("loop!")\n break\nend\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The above loop will only run once. Output:\n",(0,i.jsx)(n.code,{children:"loop!"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'x = 0\nwhile true do\n print("loop!")\n x = x + 1\n if x >=2 then\n break\n end\nend\n'})}),"\n",(0,i.jsx)(n.p,{children:"The above loop will run 2 times. Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"loop!\nloop!\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"for i = 1, 10 do\n print(i)\n if i >= 3 then\n break\n end\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"1\n2\n3\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Using ",(0,i.jsx)(n.code,{children:"break"})," is very useful! The purpose for ",(0,i.jsx)(n.code,{children:"break"})," is to stop a loop from running! So using ",(0,i.jsx)(n.code,{children:"break"})," in a for or while loop will ultimately terminate it!"]}),"\n",(0,i.jsx)(n.h3,{id:"functions-example",children:"FUNCTIONS EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local function myFunction()\n local x = 4\n local y = 2\n print(x + y)\nend\n\nmyFunction()\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"6\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local function AddNum(num1, num2)\n print(num1 + num2)\nend\n\nAddNum(99,121)\nAddNum(44,33)\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"220\n77\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local function Cubed(number)\n newNumber = number*number*number\n return newNumber\nend\n\nlocal x = Cubed(2)\nlocal y = Cubed(3)\n\nprint(x,y)\n\nlocal a = Cubed(10)\nprint(a)\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"8 27\n1000\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Functions are good for reducing the amount of code you have to write. If you have a piece of code you are going to use over and over with slightly different values, then make that piece of code a function! You can give functions ",(0,i.jsx)(n.strong,{children:"parameters"})," which is the num1 and num2 in myFunction(num1, num2). When you use the function later in your code, don't forget to fill in the parentheses! You can also use ",(0,i.jsx)(n.code,{children:"return"})," to essentially turn a function into a value."]}),"\n",(0,i.jsx)(n.h3,{id:"tables-example",children:"TABLES EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local myTable = {1,5,3}\n\nprint(myTable[1])\nprint(myTable[2])\nprint(myTable[3])\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"1\n5\n3\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'local names = {\n "Bob",\n "Moses",\n "Joe"\n}\nfor i = 1, #names do\n print(names[i])\nend\n\nnames[4] = "Dawn"\nprint(names[4])\ntable.insert(names,"Rambo")\nprint(names[5])\n'})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"Bob\nMoses\nJoe\nDawn\nRambo\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'local person = {\n health = 100,\n speed = 20,\n isAwesome = true,\n name = "John"\n}\nprint("This person\'s health is "..person.health)\nprint("This person\'s health is "..person["health"])\nprint("This person\'s speed is "..person.speed)\nprint("This person is awesome. "..person.isAwesome)\nprint("This person\'s name is "..person.name)\nprint("This person\'s name is "..person["name"])\n\nperson.home = "USA"\nperson["money"] = 250\n\nprint("This person\'s home is "..person.home)\nprint("This person has "..person["money"].." dollars!")\n\n'})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"This person's health is 100\nThis person's health is 100\nThis person's speed is 20\nThis person is awesome. true\nThis person's name is John\nThis person's name is John\nThis person's home is USA\nThis person has 250 dollars!\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Tables are very good for storing lots of information. You can even put things inside of tables after the table is made! Done with table.insert(TableName, data) or you add things with table[n] = data. And remember, the table doesn't have to be defined on the same line! The brackets "," can be on separate lines to make it easier to read!"]}),"\n",(0,i.jsx)(n.h3,{id:"for-i-v-in-pairs-loop-example",children:"FOR I, V IN PAIRS LOOP EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local numbers = {3, 4, 99, 202, -3}\n\nfor i, v in pairs(numbers) do\n print(i, v)\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"1 3\n2 4\n3 99\n4 202\n5 -3\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'local names = {"Jack", "Mike", "Melinda", "Stacy"}\n\nfor index, person in pairs(names) do\n print("Person "..index.." is "..person)\nend\n'})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"Person 1 is Jack\nPerson 2 is Mike\nPerson 3 is Melinda\nPerson 4 is Stacy\n"})}),"\n",(0,i.jsx)(n.p,{children:'For i, v in pairs loops are a useful kind of for loop! They basically go through a list and use the data stored in the table. The variable i is the index or position of the table where the data is stored. The variable v is the value of the data. Inside of pairs() is the table you want to use: pairs(TableName). The variables don\'t have to be named "i" and "v", they can be named whatever you want!'})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var i=s(6540);const r={},l=i.createContext(r);function o(e){const n=i.useContext(l);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/61036be0.c52ea3e6.js b/assets/js/61036be0.c52ea3e6.js new file mode 100644 index 0000000..80d02e2 --- /dev/null +++ b/assets/js/61036be0.c52ea3e6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[2256],{1869:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>t,contentTitle:()=>o,default:()=>h,frontMatter:()=>l,metadata:()=>a,toc:()=>d});var i=s(4848),r=s(8453);const l={sidebar_position:1},o="Beginner Lua Tutorial",a={id:"Guides/Lua/beginner",title:"Beginner Lua Tutorial",description:"https://repl.it/languages/lua can be used to try Lua in the browser.",source:"@site/docs/Guides/Lua/beginner.md",sourceDirName:"Guides/Lua",slug:"/Guides/Lua/beginner",permalink:"/ppl-docs/docs/Guides/Lua/beginner",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/Guides/Lua/beginner.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Sound files",permalink:"/ppl-docs/docs/File Information/sound-files"},next:{title:"Intermediate",permalink:"/ppl-docs/docs/Guides/Lua/intermediate"}},t={},d=[{value:"PRINTING EXAMPLE",id:"printing-example",level:3},{value:"VARIABLES EXAMPLE",id:"variables-example",level:3},{value:"IF STATEMENT EXAMPLE",id:"if-statement-example",level:3},{value:"FOR LOOP EXAMPLE",id:"for-loop-example",level:3},{value:"NESTED FOR LOOP EXAMPLE",id:"nested-for-loop-example",level:3},{value:"WHILE LOOP EXAMPLE",id:"while-loop-example",level:3},{value:"BREAK LOOPS EXAMPLE",id:"break-loops-example",level:3},{value:"FUNCTIONS EXAMPLE",id:"functions-example",level:3},{value:"TABLES EXAMPLE",id:"tables-example",level:3},{value:"FOR I, V IN PAIRS LOOP EXAMPLE",id:"for-i-v-in-pairs-loop-example",level:3}];function c(e){const n={a:"a",code:"code",h1:"h1",h3:"h3",p:"p",pre:"pre",strong:"strong",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.h1,{id:"beginner-lua-tutorial",children:"Beginner Lua Tutorial"}),"\n",(0,i.jsxs)(n.p,{children:[(0,i.jsx)(n.a,{href:"https://repl.it/languages/lua",children:"https://repl.it/languages/lua"})," can be used to try Lua in the browser."]}),"\n",(0,i.jsx)(n.p,{children:"These examples are more for review, rather than learning! If you see something here that you don't understand, continue to watch Lua tutorials on youtube!"}),"\n",(0,i.jsx)(n.h3,{id:"printing-example",children:"PRINTING EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'print("Hello world!")\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"Hello World!"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"print(2+3)\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"5"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'print("2+3")\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"2+3"})]}),"\n",(0,i.jsxs)(n.p,{children:["Anything in quotation marks ",(0,i.jsx)(n.code,{children:'" "'})," or ",(0,i.jsx)(n.code,{children:"' '"})," is a string. Printing a string will output exactly what you type! Anything not inside of quotation marks are registered as numbers, variables, or mathematics!"]}),"\n",(0,i.jsx)(n.h3,{id:"variables-example",children:"VARIABLES EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"my_variable = 5\nprint(my_variable)\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"5"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"x = 2\ny = 10\nprint(x+y)\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"12"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'x = 2\ny = 10\nprint("x+y")\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"x+y"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'some_text = "this is cool"\nprint(some_text)\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"this is cool"})]}),"\n",(0,i.jsx)(n.p,{children:"Variables can be assigned practically any value! You can store them as numbers, strings, and more!"}),"\n",(0,i.jsx)(n.h3,{id:"if-statement-example",children:"IF STATEMENT EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'x = 6\nif x > 5 then\n print("Greater than 5!")\nend\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"Greater than 5!"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'a = true\nb = false\n\nif a then\n print("True")\nend\n\nif a and b then\n print("True")\nelse\n print("False")\nend\n\nif a or b then\n print("True")\nelse\n print("False")\nend\n\nif b then\n print("True")\nend\n'})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"True\nFalse\nTrue\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'x = 5\ny = 5\nif x == y then\n print("True")\nend\n'})}),"\n",(0,i.jsxs)(n.p,{children:["Output:\n",(0,i.jsx)(n.code,{children:"True"})]}),"\n",(0,i.jsx)(n.p,{children:'Variables can also be assigned boolean values, which are true and false! With "and" statements, both or all arguments need to be true to equal true in total! With "or" statements, only one needs to be true to equal true in total! Both or all need to be false to be false in total!'}),"\n",(0,i.jsx)(n.h3,{id:"for-loop-example",children:"FOR LOOP EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'for i = 1, 5 do\n print("Hello!")\nend\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The following output is repeated 5 times:\n",(0,i.jsx)(n.code,{children:"Hello!"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"for i = 1, 10 do\n print(i)\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"for i = 1, 10, 2 do\n print(i)\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"1\n3\n5\n7\n9\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"for i = 0, -10, -1 do\n print(i)\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"0\n-1\n-2\n-3\n-4\n-5\n-6\n-7\n-8\n-9\n-10\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'local loopcount = 25\nfor i = 1, loopcount do\n print("Loop!")\nend\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The following output is repeated 25 times:\n",(0,i.jsx)(n.code,{children:"Loop!"})]}),"\n",(0,i.jsx)(n.p,{children:'For loops are useful for running the same code multiple times! The first line of the for loop has the syntax for i = Index, End Value, Increments. You set i as your starting value, separate with a comma, set your end value, and you can optionally set your increment as your third value. Don\'t forget the "do"!'}),"\n",(0,i.jsx)(n.h3,{id:"nested-for-loop-example",children:"NESTED FOR LOOP EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'for i = 1, 5 do\n print("This is the outer loop!")\n for j = 1, 3 do\n print("This is the inner loop!")\n end\nend\n'})}),"\n",(0,i.jsx)(n.p,{children:"The following output is repeated 5 times:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"This is the outer loop!\nThis is the inner loop!\nThis is the inner loop!\nThis is the inner loop!\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'local swim_laps = 10\nlocal paddles = 5\nfor i = 1, swim_laps do\n print("Lap : "..i)\n for j = 1, paddles do\n print("Paddle : "..j)\n end\nend\n'})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"Lap : 1\nPaddle : 1\nPaddle : 2\n"})}),"\n",(0,i.jsx)(n.p,{children:"...etc."}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'for i = 1, 5 do\n for i = 1, 2 do\n print("This is fine!")\n end\nend\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The following output is repeated 10 times:\n",(0,i.jsx)(n.code,{children:"This is fine!"})]}),"\n",(0,i.jsx)(n.p,{children:"You are allowed to put for loops inside of other for loops! In if you put a for loop that repeats 3 times inside of a for loop that repeats 5 times, that inner loop runs 15 times total! With for loops, you can use any variable as your index! And with nested for loops, it is good practice to use different variables, like using i and j instead of using i twice."}),"\n",(0,i.jsx)(n.h3,{id:"while-loop-example",children:"WHILE LOOP EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local x = 3\nwhile x > 0 do\n print(x)\n x = x - 1\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"3\n2\n1\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local x = 3\nlocal y = 4\nwhile x > 0 and y > 0 do\n print(x,y)\n x = x - 1\n y = y - 1\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"3 4\n2 3\n1 2\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'while true do\n print("Hello!")\nend\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The following output is repeated indefinitely:\n",(0,i.jsx)(n.code,{children:"Hello!"})]}),"\n",(0,i.jsx)(n.p,{children:"A while loop is very similar to a for loop, except you can think of it as an if statement and for loop combined! The while loop runs while the conditions are true. So for a while true do loop, the loop runs forever! Be careful when making a while true do loop!"}),"\n",(0,i.jsx)(n.h3,{id:"break-loops-example",children:"BREAK LOOPS EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'while true do\n print("loop!")\n break\nend\n'})}),"\n",(0,i.jsxs)(n.p,{children:["The above loop will only run once. Output:\n",(0,i.jsx)(n.code,{children:"loop!"})]}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'x = 0\nwhile true do\n print("loop!")\n x = x + 1\n if x >=2 then\n break\n end\nend\n'})}),"\n",(0,i.jsx)(n.p,{children:"The above loop will run 2 times. Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"loop!\nloop!\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"for i = 1, 10 do\n print(i)\n if i >= 3 then\n break\n end\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"1\n2\n3\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Using ",(0,i.jsx)(n.code,{children:"break"})," is very useful! The purpose for ",(0,i.jsx)(n.code,{children:"break"})," is to stop a loop from running! So using ",(0,i.jsx)(n.code,{children:"break"})," in a for or while loop will ultimately terminate it!"]}),"\n",(0,i.jsx)(n.h3,{id:"functions-example",children:"FUNCTIONS EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local function myFunction()\n local x = 4\n local y = 2\n print(x + y)\nend\n\nmyFunction()\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"6\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local function AddNum(num1, num2)\n print(num1 + num2)\nend\n\nAddNum(99,121)\nAddNum(44,33)\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"220\n77\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local function Cubed(number)\n newNumber = number*number*number\n return newNumber\nend\n\nlocal x = Cubed(2)\nlocal y = Cubed(3)\n\nprint(x,y)\n\nlocal a = Cubed(10)\nprint(a)\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"8 27\n1000\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Functions are good for reducing the amount of code you have to write. If you have a piece of code you are going to use over and over with slightly different values, then make that piece of code a function! You can give functions ",(0,i.jsx)(n.strong,{children:"parameters"})," which is the num1 and num2 in myFunction(num1, num2). When you use the function later in your code, don't forget to fill in the parentheses! You can also use ",(0,i.jsx)(n.code,{children:"return"})," to essentially turn a function into a value."]}),"\n",(0,i.jsx)(n.h3,{id:"tables-example",children:"TABLES EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local myTable = {1,5,3}\n\nprint(myTable[1])\nprint(myTable[2])\nprint(myTable[3])\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"1\n5\n3\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'local names = {\n "Bob",\n "Moses",\n "Joe"\n}\nfor i = 1, #names do\n print(names[i])\nend\n\nnames[4] = "Dawn"\nprint(names[4])\ntable.insert(names,"Rambo")\nprint(names[5])\n'})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"Bob\nMoses\nJoe\nDawn\nRambo\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'local person = {\n health = 100,\n speed = 20,\n isAwesome = true,\n name = "John"\n}\nprint("This person\'s health is "..person.health)\nprint("This person\'s health is "..person["health"])\nprint("This person\'s speed is "..person.speed)\nprint("This person is awesome. "..person.isAwesome)\nprint("This person\'s name is "..person.name)\nprint("This person\'s name is "..person["name"])\n\nperson.home = "USA"\nperson["money"] = 250\n\nprint("This person\'s home is "..person.home)\nprint("This person has "..person["money"].." dollars!")\n\n'})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"This person's health is 100\nThis person's health is 100\nThis person's speed is 20\nThis person is awesome. true\nThis person's name is John\nThis person's name is John\nThis person's home is USA\nThis person has 250 dollars!\n"})}),"\n",(0,i.jsxs)(n.p,{children:["Tables are very good for storing lots of information. You can even put things inside of tables after the table is made! Done with table.insert(TableName, data) or you add things with table[n] = data. And remember, the table doesn't have to be defined on the same line! The brackets "," can be on separate lines to make it easier to read!"]}),"\n",(0,i.jsx)(n.h3,{id:"for-i-v-in-pairs-loop-example",children:"FOR I, V IN PAIRS LOOP EXAMPLE"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:"local numbers = {3, 4, 99, 202, -3}\n\nfor i, v in pairs(numbers) do\n print(i, v)\nend\n"})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"1 3\n2 4\n3 99\n4 202\n5 -3\n"})}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{className:"language-lua",children:'local names = {"Jack", "Mike", "Melinda", "Stacy"}\n\nfor index, person in pairs(names) do\n print("Person "..index.." is "..person)\nend\n'})}),"\n",(0,i.jsx)(n.p,{children:"Output:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"Person 1 is Jack\nPerson 2 is Mike\nPerson 3 is Melinda\nPerson 4 is Stacy\n"})}),"\n",(0,i.jsx)(n.p,{children:'For i, v in pairs loops are a useful kind of for loop! They basically go through a list and use the data stored in the table. The variable i is the index or position of the table where the data is stored. The variable v is the value of the data. Inside of pairs() is the table you want to use: pairs(TableName). The variables don\'t have to be named "i" and "v", they can be named whatever you want!'})]})}function h(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,i.jsx)(n,{...e,children:(0,i.jsx)(c,{...e})}):c(e)}},8453:(e,n,s)=>{s.d(n,{R:()=>o,x:()=>a});var i=s(6540);const r={},l=i.createContext(r);function o(e){const n=i.useContext(l);return i.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:o(e.components),i.createElement(l.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/693aa6a8.43876ded.js b/assets/js/693aa6a8.43876ded.js new file mode 100644 index 0000000..c908400 --- /dev/null +++ b/assets/js/693aa6a8.43876ded.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[3194],{3305:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var i=n(4848),o=n(8453);const r={sidebar_position:2},s="Level restrictions",l={id:"other/level-restrictions",title:"Level restrictions",description:"Entity count",source:"@site/docs/other/level-restrictions.md",sourceDirName:"other",slug:"/other/level-restrictions",permalink:"/ppl-docs/docs/other/level-restrictions",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/other/level-restrictions.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Design principles",permalink:"/ppl-docs/docs/other/level-design-principles"},next:{title:"Trivia",permalink:"/ppl-docs/docs/other/trivia"}},a={},c=[{value:"Entity count",id:"entity-count",level:3},{value:"Duration",id:"duration",level:3},{value:"Memory usage",id:"memory-usage",level:3}];function h(e){const t={a:"a",code:"code",h1:"h1",h3:"h3",li:"li",p:"p",ul:"ul",...(0,o.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"level-restrictions",children:"Level restrictions"}),"\n",(0,i.jsx)(t.h3,{id:"entity-count",children:"Entity count"}),"\n",(0,i.jsx)(t.p,{children:"At most 1300 entities can exist at any given moment. This includes the player's bullet. If there are already 1300 entities, no more entities will be created. This means that the player won't be able to shoot."}),"\n",(0,i.jsx)(t.h3,{id:"duration",children:"Duration"}),"\n",(0,i.jsxs)(t.p,{children:["A game lasts at most 1 hour. If the level has not called ",(0,i.jsx)(t.a,{href:"https://github.com/jyaif/ppl-utils/wiki/API_pewpew_lib#void-stop_game",children:(0,i.jsx)(t.code,{children:"stop_game"})})," by then, it will be called automatically.\nThe reason for this limitation is that replays then become too large."]}),"\n",(0,i.jsx)(t.h3,{id:"memory-usage",children:"Memory usage"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"The Lua interpreter can't use more than 500KB of memory when running a level. Unless you have a memory leak in your level, this shouldn't be a problem."}),"\n",(0,i.jsx)(t.li,{children:"The Lua interpreter can't use more than 3MB of memory when loading a mesh. You will need to split a mesh into multiple files if you are hitting this limit."}),"\n",(0,i.jsx)(t.li,{children:"The Lua interpreter can't use more than 3MB of memory when loading sounds. Unless you are doing something really crazy, this will never be a problem."}),"\n"]})]})}function d(e={}){const{wrapper:t}={...(0,o.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>l});var i=n(6540);const o={},r=i.createContext(o);function s(e){const t=i.useContext(r);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),i.createElement(r.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/693aa6a8.6c33d6d2.js b/assets/js/693aa6a8.6c33d6d2.js deleted file mode 100644 index a198d4b..0000000 --- a/assets/js/693aa6a8.6c33d6d2.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[3194],{3305:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>a,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var i=n(4848),r=n(8453);const o={sidebar_position:2},s="Level restrictions",l={id:"other/level-restrictions",title:"Level restrictions",description:"Entity count",source:"@site/docs/other/level-restrictions.md",sourceDirName:"other",slug:"/other/level-restrictions",permalink:"/docs/other/level-restrictions",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/other/level-restrictions.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Design principles",permalink:"/docs/other/level-design-principles"},next:{title:"Trivia",permalink:"/docs/other/trivia"}},a={},c=[{value:"Entity count",id:"entity-count",level:3},{value:"Duration",id:"duration",level:3},{value:"Memory usage",id:"memory-usage",level:3}];function h(e){const t={a:"a",code:"code",h1:"h1",h3:"h3",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"level-restrictions",children:"Level restrictions"}),"\n",(0,i.jsx)(t.h3,{id:"entity-count",children:"Entity count"}),"\n",(0,i.jsx)(t.p,{children:"At most 1300 entities can exist at any given moment. This includes the player's bullet. If there are already 1300 entities, no more entities will be created. This means that the player won't be able to shoot."}),"\n",(0,i.jsx)(t.h3,{id:"duration",children:"Duration"}),"\n",(0,i.jsxs)(t.p,{children:["A game lasts at most 1 hour. If the level has not called ",(0,i.jsx)(t.a,{href:"https://github.com/jyaif/ppl-utils/wiki/API_pewpew_lib#void-stop_game",children:(0,i.jsx)(t.code,{children:"stop_game"})})," by then, it will be called automatically.\nThe reason for this limitation is that replays then become too large."]}),"\n",(0,i.jsx)(t.h3,{id:"memory-usage",children:"Memory usage"}),"\n",(0,i.jsxs)(t.ul,{children:["\n",(0,i.jsx)(t.li,{children:"The Lua interpreter can't use more than 500KB of memory when running a level. Unless you have a memory leak in your level, this shouldn't be a problem."}),"\n",(0,i.jsx)(t.li,{children:"The Lua interpreter can't use more than 3MB of memory when loading a mesh. You will need to split a mesh into multiple files if you are hitting this limit."}),"\n",(0,i.jsx)(t.li,{children:"The Lua interpreter can't use more than 3MB of memory when loading sounds. Unless you are doing something really crazy, this will never be a problem."}),"\n"]})]})}function u(e={}){const{wrapper:t}={...(0,r.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>l});var i=n(6540);const r={},o=i.createContext(r);function s(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function l(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:s(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7d528a0b.3ed94e94.js b/assets/js/7d528a0b.3ed94e94.js new file mode 100644 index 0000000..7e59e43 --- /dev/null +++ b/assets/js/7d528a0b.3ed94e94.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[3736],{2520:(t,e,o)=>{o.r(e),o.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var n=o(4848),s=o(8453);const r={slug:"first-blog-post",title:"First Blog Post",authors:"tastykiwi",tags:["first"]},i=void 0,a={permalink:"/ppl-docs/blog/first-blog-post",source:"@site/blog/2024-03-20-first-blog-post.md",title:"First Blog Post",description:"Welcome to the first blog article! We are so excited to move the entirety of PPL level development documentation here. This platform allows us to make more interactive (via React components), good looking documentation and having powerful search!",date:"2024-03-20T00:00:00.000Z",formattedDate:"March 20, 2024",tags:[{label:"first",permalink:"/ppl-docs/blog/tags/first"}],readingTime:.245,hasTruncateMarker:!1,authors:[{name:"Dominykas M.",title:"PewPew Live developer and creator of PPL Docs",url:"https://tastykiwi.omg.lol/",imageURL:"https://github.com/Tasty-Kiwi.png",key:"tastykiwi"}],frontMatter:{slug:"first-blog-post",title:"First Blog Post",authors:"tastykiwi",tags:["first"]},unlisted:!1},l={authorsImageUrls:[void 0]},c=[];function p(t){const e={p:"p",...(0,s.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.p,{children:"Welcome to the first blog article! We are so excited to move the entirety of PPL level development documentation here. This platform allows us to make more interactive (via React components), good looking documentation and having powerful search!"}),"\n",(0,n.jsx)(e.p,{children:"I hope you'll like the new home for PewPew docs."}),"\n",(0,n.jsx)(e.p,{children:"Enjoy!"})]})}function m(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(p,{...t})}):p(t)}},8453:(t,e,o)=>{o.d(e,{R:()=>i,x:()=>a});var n=o(6540);const s={},r=n.createContext(s);function i(t){const e=n.useContext(r);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:i(t.components),n.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/7d528a0b.e6701fa1.js b/assets/js/7d528a0b.e6701fa1.js deleted file mode 100644 index 098a43c..0000000 --- a/assets/js/7d528a0b.e6701fa1.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[3736],{2520:(t,e,o)=>{o.r(e),o.d(e,{assets:()=>l,contentTitle:()=>i,default:()=>m,frontMatter:()=>r,metadata:()=>a,toc:()=>c});var n=o(4848),s=o(8453);const r={slug:"first-blog-post",title:"First Blog Post",authors:"tastykiwi",tags:["first"]},i=void 0,a={permalink:"/blog/first-blog-post",source:"@site/blog/2024-03-20-first-blog-post.md",title:"First Blog Post",description:"Welcome to the first blog article! We are so excited to move the entirety of PPL level development documentation here. This platform allows us to make more interactive (via React components), good looking documentation and having powerful search!",date:"2024-03-20T00:00:00.000Z",formattedDate:"March 20, 2024",tags:[{label:"first",permalink:"/blog/tags/first"}],readingTime:.245,hasTruncateMarker:!1,authors:[{name:"Dominykas M.",title:"PewPew Live developer and creator of PPL Docs",url:"https://tastykiwi.omg.lol/",imageURL:"https://github.com/Tasty-Kiwi.png",key:"tastykiwi"}],frontMatter:{slug:"first-blog-post",title:"First Blog Post",authors:"tastykiwi",tags:["first"]},unlisted:!1},l={authorsImageUrls:[void 0]},c=[];function p(t){const e={p:"p",...(0,s.R)(),...t.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(e.p,{children:"Welcome to the first blog article! We are so excited to move the entirety of PPL level development documentation here. This platform allows us to make more interactive (via React components), good looking documentation and having powerful search!"}),"\n",(0,n.jsx)(e.p,{children:"I hope you'll like the new home for PewPew docs."}),"\n",(0,n.jsx)(e.p,{children:"Enjoy!"})]})}function m(t={}){const{wrapper:e}={...(0,s.R)(),...t.components};return e?(0,n.jsx)(e,{...t,children:(0,n.jsx)(p,{...t})}):p(t)}},8453:(t,e,o)=>{o.d(e,{R:()=>i,x:()=>a});var n=o(6540);const s={},r=n.createContext(s);function i(t){const e=n.useContext(r);return n.useMemo((function(){return"function"==typeof t?t(e):{...e,...t}}),[e,t])}function a(t){let e;return e=t.disableParentContext?"function"==typeof t.components?t.components(s):t.components||s:i(t.components),n.createElement(r.Provider,{value:e},t.children)}}}]); \ No newline at end of file diff --git a/assets/js/814f3328.3297c513.js b/assets/js/814f3328.dcabf658.js similarity index 51% rename from assets/js/814f3328.3297c513.js rename to assets/js/814f3328.dcabf658.js index c693518..f43179d 100644 --- a/assets/js/814f3328.3297c513.js +++ b/assets/js/814f3328.dcabf658.js @@ -1 +1 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[7472],{5513:s=>{s.exports=JSON.parse('{"title":"Recent posts","items":[{"title":"First Blog Post","permalink":"/blog/first-blog-post","unlisted":false}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[7472],{5513:s=>{s.exports=JSON.parse('{"title":"Recent posts","items":[{"title":"First Blog Post","permalink":"/ppl-docs/blog/first-blog-post","unlisted":false}]}')}}]); \ No newline at end of file diff --git a/assets/js/91cb3e84.5866b4f7.js b/assets/js/91cb3e84.5866b4f7.js deleted file mode 100644 index f0a6157..0000000 --- a/assets/js/91cb3e84.5866b4f7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[298],{7962:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>x,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var t=i(4848),d=i(8453);const s={sidebar_position:3},r="fmath library",a={id:"APIs/Fmath",title:"Fmath",description:"fmath contains a set of mathematical functions that work with FixedPoint numbers and integers. fmath replaces Lua's math library in game scripts (you can use Lua's math library outside of game scripts).",source:"@site/docs/APIs/Fmath.md",sourceDirName:"APIs",slug:"/APIs/Fmath",permalink:"/docs/APIs/Fmath",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/APIs/Fmath.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"PewPew",permalink:"/docs/APIs/PewPew"},next:{title:"Standard libraries",permalink:"/docs/APIs/standard-libraries"}},o={},c=[{value:"Functions",id:"functions",level:2},{value:"max_fixedpoint()",id:"max_fixedpoint",level:3},{value:"random_fixedpoint()",id:"random_fixedpoint",level:3},{value:"random_int()",id:"random_int",level:3},{value:"sqrt()",id:"sqrt",level:3},{value:"from_fraction()",id:"from_fraction",level:3},{value:"to_int()",id:"to_int",level:3},{value:"abs_fixedpoint()",id:"abs_fixedpoint",level:3},{value:"to_fixedpoint()",id:"to_fixedpoint",level:3},{value:"sincos()",id:"sincos",level:3},{value:"atan2()",id:"atan2",level:3},{value:"tau()",id:"tau",level:3}];function l(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",hr:"hr",p:"p",pre:"pre",...(0,d.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"fmath-library",children:"fmath library"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"fmath"})," contains a set of mathematical functions that work with FixedPoint numbers and integers. ",(0,t.jsx)(n.code,{children:"fmath"})," replaces Lua's ",(0,t.jsx)(n.code,{children:"math"})," library in game scripts (you can use Lua's ",(0,t.jsx)(n.code,{children:"math"})," library outside of game scripts)."]}),"\n",(0,t.jsx)(n.h2,{id:"functions",children:"Functions"}),"\n",(0,t.jsx)(n.h3,{id:"max_fixedpoint",children:(0,t.jsx)(n.code,{children:"max_fixedpoint()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.max_fixedpoint(): FixedPoint\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns the maximum value a fixedpoint integer can take."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"random_fixedpoint",children:(0,t.jsx)(n.code,{children:"random_fixedpoint()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.random_fixedpoint(\n min: FixedPoint,\n max: FixedPoint\n): FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns a random fixedpoint value in the range [",(0,t.jsx)(n.code,{children:"min"}),", ",(0,t.jsx)(n.code,{children:"max"}),"]. ",(0,t.jsx)(n.code,{children:"max"})," must be greater or equal to ",(0,t.jsx)(n.code,{children:"min"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"random_int",children:(0,t.jsx)(n.code,{children:"random_int()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.random_int(\n min: int,\n max: int\n): int\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns an integer in the range [",(0,t.jsx)(n.code,{children:"min"}),", ",(0,t.jsx)(n.code,{children:"max"}),"]. ",(0,t.jsx)(n.code,{children:"max"})," must be greater or equal to ",(0,t.jsx)(n.code,{children:"min"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"sqrt",children:(0,t.jsx)(n.code,{children:"sqrt()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.sqrt(x: FixedPoint): FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the square root of ",(0,t.jsx)(n.code,{children:"x"}),". ",(0,t.jsx)(n.code,{children:"x"})," must be greater or equal to 0."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"from_fraction",children:(0,t.jsx)(n.code,{children:"from_fraction()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.from_fraction(\n numerator: int,\n denominator: int\n): FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the fixedpoint value representing the fraction ",(0,t.jsx)(n.code,{children:"numerator"}),"/",(0,t.jsx)(n.code,{children:"denominator"}),". ",(0,t.jsx)(n.code,{children:"denominator"})," must not be equal to zero."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"to_int",children:(0,t.jsx)(n.code,{children:"to_int()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.to_int(value: FixedPoint): int\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the integral part of the ",(0,t.jsx)(n.code,{children:"value"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"abs_fixedpoint",children:(0,t.jsx)(n.code,{children:"abs_fixedpoint()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.abs_fixedpoint(value: FixedPoint): FixedPoint\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns the absolute value."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"to_fixedpoint",children:(0,t.jsx)(n.code,{children:"to_fixedpoint()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.to_fixedpoint(value: int): FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns a fixedpoint value with the integral part of ",(0,t.jsx)(n.code,{children:"value"}),", and no fractional part."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"sincos",children:(0,t.jsx)(n.code,{children:"sincos()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.sincos(angle: FixedPoint): FixedPoint, FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the sinus and cosinus of ",(0,t.jsx)(n.code,{children:"angle"}),". ",(0,t.jsx)(n.code,{children:"angle"})," is in radian."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"atan2",children:(0,t.jsx)(n.code,{children:"atan2()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.atan2(\n y: FixedPoint,\n x: FixedPoint\n): FixedPoint\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns the principal value of the arc tangent of y/x. Returns a value in the range [0, 2\u03c0[."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"tau",children:(0,t.jsx)(n.code,{children:"tau()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.tau(): FixedPoint\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns \u03c4 (aka 2\u03c0)."})]})}function x(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>a});var t=i(6540);const d={},s=t.createContext(d);function r(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:r(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/91cb3e84.5acf482c.js b/assets/js/91cb3e84.5acf482c.js new file mode 100644 index 0000000..418901c --- /dev/null +++ b/assets/js/91cb3e84.5acf482c.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[298],{7962:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>o,contentTitle:()=>r,default:()=>x,frontMatter:()=>s,metadata:()=>a,toc:()=>c});var t=i(4848),d=i(8453);const s={sidebar_position:3},r="fmath library",a={id:"APIs/Fmath",title:"Fmath",description:"fmath contains a set of mathematical functions that work with FixedPoint numbers and integers. fmath replaces Lua's math library in game scripts (you can use Lua's math library outside of game scripts).",source:"@site/docs/APIs/Fmath.md",sourceDirName:"APIs",slug:"/APIs/Fmath",permalink:"/ppl-docs/docs/APIs/Fmath",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/APIs/Fmath.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"PewPew",permalink:"/ppl-docs/docs/APIs/PewPew"},next:{title:"Standard libraries",permalink:"/ppl-docs/docs/APIs/standard-libraries"}},o={},c=[{value:"Functions",id:"functions",level:2},{value:"max_fixedpoint()",id:"max_fixedpoint",level:3},{value:"random_fixedpoint()",id:"random_fixedpoint",level:3},{value:"random_int()",id:"random_int",level:3},{value:"sqrt()",id:"sqrt",level:3},{value:"from_fraction()",id:"from_fraction",level:3},{value:"to_int()",id:"to_int",level:3},{value:"abs_fixedpoint()",id:"abs_fixedpoint",level:3},{value:"to_fixedpoint()",id:"to_fixedpoint",level:3},{value:"sincos()",id:"sincos",level:3},{value:"atan2()",id:"atan2",level:3},{value:"tau()",id:"tau",level:3}];function l(e){const n={code:"code",h1:"h1",h2:"h2",h3:"h3",hr:"hr",p:"p",pre:"pre",...(0,d.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(n.h1,{id:"fmath-library",children:"fmath library"}),"\n",(0,t.jsxs)(n.p,{children:[(0,t.jsx)(n.code,{children:"fmath"})," contains a set of mathematical functions that work with FixedPoint numbers and integers. ",(0,t.jsx)(n.code,{children:"fmath"})," replaces Lua's ",(0,t.jsx)(n.code,{children:"math"})," library in game scripts (you can use Lua's ",(0,t.jsx)(n.code,{children:"math"})," library outside of game scripts)."]}),"\n",(0,t.jsx)(n.h2,{id:"functions",children:"Functions"}),"\n",(0,t.jsx)(n.h3,{id:"max_fixedpoint",children:(0,t.jsx)(n.code,{children:"max_fixedpoint()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.max_fixedpoint(): FixedPoint\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns the maximum value a fixedpoint integer can take."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"random_fixedpoint",children:(0,t.jsx)(n.code,{children:"random_fixedpoint()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.random_fixedpoint(\n min: FixedPoint,\n max: FixedPoint\n): FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns a random fixedpoint value in the range [",(0,t.jsx)(n.code,{children:"min"}),", ",(0,t.jsx)(n.code,{children:"max"}),"]. ",(0,t.jsx)(n.code,{children:"max"})," must be greater or equal to ",(0,t.jsx)(n.code,{children:"min"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"random_int",children:(0,t.jsx)(n.code,{children:"random_int()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.random_int(\n min: int,\n max: int\n): int\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns an integer in the range [",(0,t.jsx)(n.code,{children:"min"}),", ",(0,t.jsx)(n.code,{children:"max"}),"]. ",(0,t.jsx)(n.code,{children:"max"})," must be greater or equal to ",(0,t.jsx)(n.code,{children:"min"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"sqrt",children:(0,t.jsx)(n.code,{children:"sqrt()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.sqrt(x: FixedPoint): FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the square root of ",(0,t.jsx)(n.code,{children:"x"}),". ",(0,t.jsx)(n.code,{children:"x"})," must be greater or equal to 0."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"from_fraction",children:(0,t.jsx)(n.code,{children:"from_fraction()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.from_fraction(\n numerator: int,\n denominator: int\n): FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the fixedpoint value representing the fraction ",(0,t.jsx)(n.code,{children:"numerator"}),"/",(0,t.jsx)(n.code,{children:"denominator"}),". ",(0,t.jsx)(n.code,{children:"denominator"})," must not be equal to zero."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"to_int",children:(0,t.jsx)(n.code,{children:"to_int()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.to_int(value: FixedPoint): int\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the integral part of the ",(0,t.jsx)(n.code,{children:"value"}),"."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"abs_fixedpoint",children:(0,t.jsx)(n.code,{children:"abs_fixedpoint()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.abs_fixedpoint(value: FixedPoint): FixedPoint\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns the absolute value."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"to_fixedpoint",children:(0,t.jsx)(n.code,{children:"to_fixedpoint()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.to_fixedpoint(value: int): FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns a fixedpoint value with the integral part of ",(0,t.jsx)(n.code,{children:"value"}),", and no fractional part."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"sincos",children:(0,t.jsx)(n.code,{children:"sincos()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.sincos(angle: FixedPoint): FixedPoint, FixedPoint\n"})}),"\n",(0,t.jsxs)(n.p,{children:["Returns the sinus and cosinus of ",(0,t.jsx)(n.code,{children:"angle"}),". ",(0,t.jsx)(n.code,{children:"angle"})," is in radian."]}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"atan2",children:(0,t.jsx)(n.code,{children:"atan2()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.atan2(\n y: FixedPoint,\n x: FixedPoint\n): FixedPoint\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns the principal value of the arc tangent of y/x. Returns a value in the range [0, 2\u03c0[."}),"\n",(0,t.jsx)(n.hr,{}),"\n",(0,t.jsx)(n.h3,{id:"tau",children:(0,t.jsx)(n.code,{children:"tau()"})}),"\n",(0,t.jsx)(n.pre,{children:(0,t.jsx)(n.code,{className:"language-tsx",children:"fmath.tau(): FixedPoint\n"})}),"\n",(0,t.jsx)(n.p,{children:"Returns \u03c4 (aka 2\u03c0)."})]})}function x(e={}){const{wrapper:n}={...(0,d.R)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(l,{...e})}):l(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>r,x:()=>a});var t=i(6540);const d={},s=t.createContext(d);function r(e){const n=t.useContext(s);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(d):e.components||d:r(e.components),t.createElement(s.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.5006d101.js b/assets/js/935f2afb.5006d101.js new file mode 100644 index 0000000..3eb427d --- /dev/null +++ b/assets/js/935f2afb.5006d101.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[8581],{5610:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Introduction","href":"/ppl-docs/docs/intro","docId":"intro","unlisted":false},{"type":"category","label":"APIs","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Types","href":"/ppl-docs/docs/APIs/types","docId":"APIs/types","unlisted":false},{"type":"link","label":"PewPew","href":"/ppl-docs/docs/APIs/PewPew","docId":"APIs/PewPew","unlisted":false},{"type":"link","label":"Fmath","href":"/ppl-docs/docs/APIs/Fmath","docId":"APIs/Fmath","unlisted":false},{"type":"link","label":"Standard libraries","href":"/ppl-docs/docs/APIs/standard-libraries","docId":"APIs/standard-libraries","unlisted":false}]},{"type":"category","label":"File Information","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Manifest files","href":"/ppl-docs/docs/File Information/manifest-files","docId":"File Information/manifest-files","unlisted":false},{"type":"link","label":"Mesh files","href":"/ppl-docs/docs/File Information/mesh-files","docId":"File Information/mesh-files","unlisted":false},{"type":"link","label":"Sound files","href":"/ppl-docs/docs/File Information/sound-files","docId":"File Information/sound-files","unlisted":false}]},{"type":"category","label":"Guides","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Lua","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Beginner Lua Tutorial","href":"/ppl-docs/docs/Guides/Lua/beginner","docId":"Guides/Lua/beginner","unlisted":false},{"type":"link","label":"Intermediate","href":"/ppl-docs/docs/Guides/Lua/intermediate","docId":"Guides/Lua/intermediate","unlisted":false},{"type":"link","label":"Advanced","href":"/ppl-docs/docs/Guides/Lua/advanced","docId":"Guides/Lua/advanced","unlisted":false}]},{"type":"category","label":"Other","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"60 FPS Animation","href":"/ppl-docs/docs/Guides/Other/fps-animation","docId":"Guides/Other/fps-animation","unlisted":false}]}]},{"type":"category","label":"other","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Design principles","href":"/ppl-docs/docs/other/level-design-principles","docId":"other/level-design-principles","unlisted":false},{"type":"link","label":"Level restrictions","href":"/ppl-docs/docs/other/level-restrictions","docId":"other/level-restrictions","unlisted":false},{"type":"link","label":"Trivia","href":"/ppl-docs/docs/other/trivia","docId":"other/trivia","unlisted":false}]}]},"docs":{"APIs/Fmath":{"id":"APIs/Fmath","title":"Fmath","description":"fmath contains a set of mathematical functions that work with FixedPoint numbers and integers. fmath replaces Lua\'s math library in game scripts (you can use Lua\'s math library outside of game scripts).","sidebar":"tutorialSidebar"},"APIs/PewPew":{"id":"APIs/PewPew","title":"PewPew","description":"The pewpew library contains all the functions for configuring levels and managing entities.","sidebar":"tutorialSidebar"},"APIs/standard-libraries":{"id":"APIs/standard-libraries","title":"Standard libraries","description":"Only a subset of the standard Lua libraries are available in PewPew Live:","sidebar":"tutorialSidebar"},"APIs/types":{"id":"APIs/types","title":"Types","description":"int","sidebar":"tutorialSidebar"},"File Information/manifest-files":{"id":"File Information/manifest-files","title":"Manifest files","description":"Manifests are written in JSON.","sidebar":"tutorialSidebar"},"File Information/mesh-files":{"id":"File Information/mesh-files","title":"Mesh files","description":"In PewPew Live, a mesh is a collection of lines in 3D.","sidebar":"tutorialSidebar"},"File Information/sound-files":{"id":"File Information/sound-files","title":"Sound files","description":"Example of a file that defines a single sound:","sidebar":"tutorialSidebar"},"Guides/Lua/advanced":{"id":"Guides/Lua/advanced","title":"Advanced","description":"In this tutorial, we will learn how to make more advanced levels, including meshes, custom enemies, and other cool gameplay features!","sidebar":"tutorialSidebar"},"Guides/Lua/beginner":{"id":"Guides/Lua/beginner","title":"Beginner Lua Tutorial","description":"https://repl.it/languages/lua can be used to try Lua in the browser.","sidebar":"tutorialSidebar"},"Guides/Lua/intermediate":{"id":"Guides/Lua/intermediate","title":"Intermediate","description":"If you are here, you made it through the learning process of the Lua language! Keep in mind, this section assumes that you know basic Lua. If you need to freshen up, look back onto the Beginner tutorials!","sidebar":"tutorialSidebar"},"Guides/Other/fps-animation":{"id":"Guides/Other/fps-animation","title":"60 FPS Animation","description":"Tutorial created by WinterNox.","sidebar":"tutorialSidebar"},"intro":{"id":"intro","title":"Introduction","description":"This community-maintained wiki holds the resources useful for creating custom levels for PewPew Live.","sidebar":"tutorialSidebar"},"other/level-design-principles":{"id":"other/level-design-principles","title":"Design principles","description":"General guidelines","sidebar":"tutorialSidebar"},"other/level-restrictions":{"id":"other/level-restrictions","title":"Level restrictions","description":"Entity count","sidebar":"tutorialSidebar"},"other/trivia":{"id":"other/trivia","title":"Trivia","description":"This page contains a random bag of technical information concerning PewPew Live.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/935f2afb.6c981c69.js b/assets/js/935f2afb.6c981c69.js deleted file mode 100644 index 2221233..0000000 --- a/assets/js/935f2afb.6c981c69.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[8581],{5610:e=>{e.exports=JSON.parse('{"pluginId":"default","version":"current","label":"Next","banner":null,"badge":false,"noIndex":false,"className":"docs-version-current","isLast":true,"docsSidebars":{"tutorialSidebar":[{"type":"link","label":"Introduction","href":"/docs/intro","docId":"intro","unlisted":false},{"type":"category","label":"APIs","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Types","href":"/docs/APIs/types","docId":"APIs/types","unlisted":false},{"type":"link","label":"PewPew","href":"/docs/APIs/PewPew","docId":"APIs/PewPew","unlisted":false},{"type":"link","label":"Fmath","href":"/docs/APIs/Fmath","docId":"APIs/Fmath","unlisted":false},{"type":"link","label":"Standard libraries","href":"/docs/APIs/standard-libraries","docId":"APIs/standard-libraries","unlisted":false}]},{"type":"category","label":"File Information","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Manifest files","href":"/docs/File Information/manifest-files","docId":"File Information/manifest-files","unlisted":false},{"type":"link","label":"Mesh files","href":"/docs/File Information/mesh-files","docId":"File Information/mesh-files","unlisted":false},{"type":"link","label":"Sound files","href":"/docs/File Information/sound-files","docId":"File Information/sound-files","unlisted":false}]},{"type":"category","label":"Guides","collapsible":true,"collapsed":true,"items":[{"type":"category","label":"Lua","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Beginner Lua Tutorial","href":"/docs/Guides/Lua/beginner","docId":"Guides/Lua/beginner","unlisted":false},{"type":"link","label":"Intermediate","href":"/docs/Guides/Lua/intermediate","docId":"Guides/Lua/intermediate","unlisted":false},{"type":"link","label":"Advanced","href":"/docs/Guides/Lua/advanced","docId":"Guides/Lua/advanced","unlisted":false}]},{"type":"category","label":"Other","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"60 FPS Animation","href":"/docs/Guides/Other/fps-animation","docId":"Guides/Other/fps-animation","unlisted":false}]}]},{"type":"category","label":"other","collapsible":true,"collapsed":true,"items":[{"type":"link","label":"Design principles","href":"/docs/other/level-design-principles","docId":"other/level-design-principles","unlisted":false},{"type":"link","label":"Level restrictions","href":"/docs/other/level-restrictions","docId":"other/level-restrictions","unlisted":false},{"type":"link","label":"Trivia","href":"/docs/other/trivia","docId":"other/trivia","unlisted":false}]}]},"docs":{"APIs/Fmath":{"id":"APIs/Fmath","title":"Fmath","description":"fmath contains a set of mathematical functions that work with FixedPoint numbers and integers. fmath replaces Lua\'s math library in game scripts (you can use Lua\'s math library outside of game scripts).","sidebar":"tutorialSidebar"},"APIs/PewPew":{"id":"APIs/PewPew","title":"PewPew","description":"The pewpew library contains all the functions for configuring levels and managing entities.","sidebar":"tutorialSidebar"},"APIs/standard-libraries":{"id":"APIs/standard-libraries","title":"Standard libraries","description":"Only a subset of the standard Lua libraries are available in PewPew Live:","sidebar":"tutorialSidebar"},"APIs/types":{"id":"APIs/types","title":"Types","description":"int","sidebar":"tutorialSidebar"},"File Information/manifest-files":{"id":"File Information/manifest-files","title":"Manifest files","description":"Manifests are written in JSON.","sidebar":"tutorialSidebar"},"File Information/mesh-files":{"id":"File Information/mesh-files","title":"Mesh files","description":"In PewPew Live, a mesh is a collection of lines in 3D.","sidebar":"tutorialSidebar"},"File Information/sound-files":{"id":"File Information/sound-files","title":"Sound files","description":"Example of a file that defines a single sound:","sidebar":"tutorialSidebar"},"Guides/Lua/advanced":{"id":"Guides/Lua/advanced","title":"Advanced","description":"In this tutorial, we will learn how to make more advanced levels, including meshes, custom enemies, and other cool gameplay features!","sidebar":"tutorialSidebar"},"Guides/Lua/beginner":{"id":"Guides/Lua/beginner","title":"Beginner Lua Tutorial","description":"https://repl.it/languages/lua can be used to try Lua in the browser.","sidebar":"tutorialSidebar"},"Guides/Lua/intermediate":{"id":"Guides/Lua/intermediate","title":"Intermediate","description":"If you are here, you made it through the learning process of the Lua language! Keep in mind, this section assumes that you know basic Lua. If you need to freshen up, look back onto the Beginner tutorials!","sidebar":"tutorialSidebar"},"Guides/Other/fps-animation":{"id":"Guides/Other/fps-animation","title":"60 FPS Animation","description":"Tutorial created by WinterNox.","sidebar":"tutorialSidebar"},"intro":{"id":"intro","title":"Introduction","description":"This community-maintained wiki holds the resources useful for creating custom levels for PewPew Live.","sidebar":"tutorialSidebar"},"other/level-design-principles":{"id":"other/level-design-principles","title":"Design principles","description":"General guidelines","sidebar":"tutorialSidebar"},"other/level-restrictions":{"id":"other/level-restrictions","title":"Level restrictions","description":"Entity count","sidebar":"tutorialSidebar"},"other/trivia":{"id":"other/trivia","title":"Trivia","description":"This page contains a random bag of technical information concerning PewPew Live.","sidebar":"tutorialSidebar"}}}')}}]); \ No newline at end of file diff --git a/assets/js/9a119d2a.ff84d629.js b/assets/js/9a119d2a.ff84d629.js deleted file mode 100644 index dcd6d98..0000000 --- a/assets/js/9a119d2a.ff84d629.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[1387],{490:s=>{s.exports=JSON.parse('{"label":"first","permalink":"/blog/tags/first","allTagsPath":"/blog/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/a7023ddc.0176f139.js b/assets/js/a7023ddc.0176f139.js deleted file mode 100644 index 6a2e35f..0000000 --- a/assets/js/a7023ddc.0176f139.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[9267],{8289:s=>{s.exports=JSON.parse('[{"label":"first","permalink":"/blog/tags/first","count":1}]')}}]); \ No newline at end of file diff --git a/assets/js/b204be58.580218a5.js b/assets/js/b204be58.580218a5.js deleted file mode 100644 index 4051243..0000000 --- a/assets/js/b204be58.580218a5.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[9363],{3621:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>p,frontMatter:()=>a,metadata:()=>d,toc:()=>u});var i=n(4848),s=n(8453),o=n(6540);function r(){const[e,t]=(0,o.useState)("2.718"),n=(0,o.useRef)(null);return(0,i.jsxs)("div",{children:[(0,i.jsx)("input",{type:"text",defaultValue:"2.718",onInput:e=>t(e.target.value)}),(0,i.jsx)("input",{type:"button",defaultValue:"to FixedPoint \u2192",onClick:()=>{n.current.value=function(e){let t=parseFloat(e),n=Math.abs(t),i=Math.floor(n);i>2<<51&&(i=2<<51);let s=t<0?"-":"",o=Math.floor(n%1*4096),r="";return 0!=o&&(r="."+o),`${s}${i}${r}fx`}(e)}}),(0,i.jsx)("input",{type:"text",readonly:!0,ref:n})]})}const a={sidebar_position:1},l="Types",d={id:"APIs/types",title:"Types",description:"int",source:"@site/docs/APIs/types.mdx",sourceDirName:"APIs",slug:"/APIs/types",permalink:"/docs/APIs/types",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/APIs/types.mdx",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Introduction",permalink:"/docs/intro"},next:{title:"PewPew",permalink:"/docs/APIs/PewPew"}},c={},u=[{value:"int",id:"int",level:2},{value:"FixedPoint",id:"fixedpoint",level:2},{value:"EntityId",id:"entityid",level:2},{value:"String",id:"string",level:2},{value:"float",id:"float",level:2}];function h(e){const t={code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"types",children:"Types"}),"\n",(0,i.jsx)(t.h2,{id:"int",children:"int"}),"\n",(0,i.jsx)(t.p,{children:"Stores integers. Used for many things, including durations and colors.\nDurations represents a number of game ticks. There are 30 game ticks per seconds. For example, a duration of 45 ticks represents 1.5 seconds.\nColors are stored in 32 bits in the RGBA order. For example, 0xff000080 encodes pure red (0xff0000) with an alpha value of 0x80."}),"\n",(0,i.jsx)(t.h2,{id:"fixedpoint",children:"FixedPoint"}),"\n",(0,i.jsx)(t.p,{children:"Stores fixed point numbers.\nUsed for storing and computing all the game related values that require more precision than what integer numbers can provide. That includes coordinates, angles, velocities, etc...\nThis built-in type is specific to PewPew, and does not exist in other Lua interpreters, which is why it is documented more thoroughly than the other types.\nA FixedPoint constant is defined using a number followed by the fx postfix:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-lua",children:"local a = 100fx\n"})}),"\n",(0,i.jsx)(t.p,{children:"You can perform regular arithmetic operations on it (+, -, /, *, <, ==, >, and, or, xor), but you can't mix FixedPoint values with non-FixedPoint values:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-lua",children:"local a = 100fx\nlocal b = a / 3fx -- Ok\nlocal c = a / 3 -- Not ok! 3 is not a FixedPoint\n"})}),"\n",(0,i.jsx)(t.p,{children:"Internally, FixedPoint numbers are implemented using dux_fixed, which uses 64 bits integers. 52 bits are used to encode the integral part, leaving 12 bits for the fractional part.\nYou can initialize the fractional part by placing a '.' followed by an integer in the range [0, 4095]:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-lua",children:"local a = 1fx -- Stores the value 1\nlocal b = 1.0fx -- Stores the value 1\nlocal c = 1.2048fx -- Stores the value 1.5\nlocal d = 1.4095fx -- Stores the value 1.9997558...\nlocal e = -1.4095fx -- Stores the value -1.9997558...\nlocal f = 1.4096fx -- Not ok! The decimal part must be less than 4096\n"})}),"\n",(0,i.jsx)(t.p,{children:"Here's an interactive converter that can help understanding the format:"}),"\n",(0,i.jsx)(r,{}),"\n",(0,i.jsx)(t.h2,{id:"entityid",children:"EntityId"}),"\n",(0,i.jsx)(t.p,{children:"An integer that identifies an entity. EntityIds are guaranteed to be unique: they are not reused for the duration of a game."}),"\n",(0,i.jsx)(t.h2,{id:"string",children:"String"}),"\n",(0,i.jsx)(t.p,{children:"Stores a sequence of characters.\nTypically used to hold text and file paths. The API only accepts strings less than 1000 bytes long."}),"\n",(0,i.jsx)(t.h2,{id:"float",children:"float"}),"\n",(0,i.jsx)(t.p,{children:"Stores floating point numbers. Because they make determinism hard to guarantee, floats must only be used in Lua scripts that define meshes or sounds. Although it is still technically possible to use floats in game scripts, they will eventually be forbidden."})]})}function p(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(h,{...e})}):h(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var i=n(6540);const s={},o=i.createContext(s);function r(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b204be58.5f262826.js b/assets/js/b204be58.5f262826.js new file mode 100644 index 0000000..e3325f9 --- /dev/null +++ b/assets/js/b204be58.5f262826.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[9363],{3621:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>l,default:()=>h,frontMatter:()=>a,metadata:()=>d,toc:()=>u});var i=n(4848),s=n(8453),o=n(6540);function r(){const[e,t]=(0,o.useState)("2.718"),n=(0,o.useRef)(null);return(0,i.jsxs)("div",{children:[(0,i.jsx)("input",{type:"text",defaultValue:"2.718",onInput:e=>t(e.target.value)}),(0,i.jsx)("input",{type:"button",defaultValue:"to FixedPoint \u2192",onClick:()=>{n.current.value=function(e){let t=parseFloat(e),n=Math.abs(t),i=Math.floor(n);i>2<<51&&(i=2<<51);let s=t<0?"-":"",o=Math.floor(n%1*4096),r="";return 0!=o&&(r="."+o),`${s}${i}${r}fx`}(e)}}),(0,i.jsx)("input",{type:"text",readonly:!0,ref:n})]})}const a={sidebar_position:1},l="Types",d={id:"APIs/types",title:"Types",description:"int",source:"@site/docs/APIs/types.mdx",sourceDirName:"APIs",slug:"/APIs/types",permalink:"/ppl-docs/docs/APIs/types",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/APIs/types.mdx",tags:[],version:"current",sidebarPosition:1,frontMatter:{sidebar_position:1},sidebar:"tutorialSidebar",previous:{title:"Introduction",permalink:"/ppl-docs/docs/intro"},next:{title:"PewPew",permalink:"/ppl-docs/docs/APIs/PewPew"}},c={},u=[{value:"int",id:"int",level:2},{value:"FixedPoint",id:"fixedpoint",level:2},{value:"EntityId",id:"entityid",level:2},{value:"String",id:"string",level:2},{value:"float",id:"float",level:2}];function p(e){const t={code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",...(0,s.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h1,{id:"types",children:"Types"}),"\n",(0,i.jsx)(t.h2,{id:"int",children:"int"}),"\n",(0,i.jsx)(t.p,{children:"Stores integers. Used for many things, including durations and colors.\nDurations represents a number of game ticks. There are 30 game ticks per seconds. For example, a duration of 45 ticks represents 1.5 seconds.\nColors are stored in 32 bits in the RGBA order. For example, 0xff000080 encodes pure red (0xff0000) with an alpha value of 0x80."}),"\n",(0,i.jsx)(t.h2,{id:"fixedpoint",children:"FixedPoint"}),"\n",(0,i.jsx)(t.p,{children:"Stores fixed point numbers.\nUsed for storing and computing all the game related values that require more precision than what integer numbers can provide. That includes coordinates, angles, velocities, etc...\nThis built-in type is specific to PewPew, and does not exist in other Lua interpreters, which is why it is documented more thoroughly than the other types.\nA FixedPoint constant is defined using a number followed by the fx postfix:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-lua",children:"local a = 100fx\n"})}),"\n",(0,i.jsx)(t.p,{children:"You can perform regular arithmetic operations on it (+, -, /, *, <, ==, >, and, or, xor), but you can't mix FixedPoint values with non-FixedPoint values:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-lua",children:"local a = 100fx\nlocal b = a / 3fx -- Ok\nlocal c = a / 3 -- Not ok! 3 is not a FixedPoint\n"})}),"\n",(0,i.jsx)(t.p,{children:"Internally, FixedPoint numbers are implemented using dux_fixed, which uses 64 bits integers. 52 bits are used to encode the integral part, leaving 12 bits for the fractional part.\nYou can initialize the fractional part by placing a '.' followed by an integer in the range [0, 4095]:"}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-lua",children:"local a = 1fx -- Stores the value 1\nlocal b = 1.0fx -- Stores the value 1\nlocal c = 1.2048fx -- Stores the value 1.5\nlocal d = 1.4095fx -- Stores the value 1.9997558...\nlocal e = -1.4095fx -- Stores the value -1.9997558...\nlocal f = 1.4096fx -- Not ok! The decimal part must be less than 4096\n"})}),"\n",(0,i.jsx)(t.p,{children:"Here's an interactive converter that can help understanding the format:"}),"\n",(0,i.jsx)(r,{}),"\n",(0,i.jsx)(t.h2,{id:"entityid",children:"EntityId"}),"\n",(0,i.jsx)(t.p,{children:"An integer that identifies an entity. EntityIds are guaranteed to be unique: they are not reused for the duration of a game."}),"\n",(0,i.jsx)(t.h2,{id:"string",children:"String"}),"\n",(0,i.jsx)(t.p,{children:"Stores a sequence of characters.\nTypically used to hold text and file paths. The API only accepts strings less than 1000 bytes long."}),"\n",(0,i.jsx)(t.h2,{id:"float",children:"float"}),"\n",(0,i.jsx)(t.p,{children:"Stores floating point numbers. Because they make determinism hard to guarantee, floats must only be used in Lua scripts that define meshes or sounds. Although it is still technically possible to use floats in game scripts, they will eventually be forbidden."})]})}function h(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(p,{...e})}):p(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>a});var i=n(6540);const s={},o=i.createContext(s);function r(e){const t=i.useContext(o);return i.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function a(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),i.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/b2b675dd.e4ac76a4.js b/assets/js/b2b675dd.e4ac76a4.js deleted file mode 100644 index f868127..0000000 --- a/assets/js/b2b675dd.e4ac76a4.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[1991],{9775:e=>{e.exports=JSON.parse('{"permalink":"/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/b2f554cd.44cb7583.js b/assets/js/b2f554cd.44cb7583.js deleted file mode 100644 index 98bf761..0000000 --- a/assets/js/b2f554cd.44cb7583.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[5894],{6042:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"first-blog-post","metadata":{"permalink":"/blog/first-blog-post","source":"@site/blog/2024-03-20-first-blog-post.md","title":"First Blog Post","description":"Welcome to the first blog article! We are so excited to move the entirety of PPL level development documentation here. This platform allows us to make more interactive (via React components), good looking documentation and having powerful search!","date":"2024-03-20T00:00:00.000Z","formattedDate":"March 20, 2024","tags":[{"label":"first","permalink":"/blog/tags/first"}],"readingTime":0.245,"hasTruncateMarker":false,"authors":[{"name":"Dominykas M.","title":"PewPew Live developer and creator of PPL Docs","url":"https://tastykiwi.omg.lol/","imageURL":"https://github.com/Tasty-Kiwi.png","key":"tastykiwi"}],"frontMatter":{"slug":"first-blog-post","title":"First Blog Post","authors":"tastykiwi","tags":["first"]},"unlisted":false},"content":"Welcome to the first blog article! We are so excited to move the entirety of PPL level development documentation here. This platform allows us to make more interactive (via React components), good looking documentation and having powerful search!\\n\\nI hope you\'ll like the new home for PewPew docs.\\n\\nEnjoy!"}]}')}}]); \ No newline at end of file diff --git a/assets/js/b745e581.233e377a.js b/assets/js/b745e581.233e377a.js deleted file mode 100644 index 270f9f1..0000000 --- a/assets/js/b745e581.233e377a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[8064],{2705:s=>{s.exports=JSON.parse('{"permalink":"/blog/tags/first","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/ba59bd01.86a404f3.js b/assets/js/ba59bd01.86a404f3.js new file mode 100644 index 0000000..8d815b4 --- /dev/null +++ b/assets/js/ba59bd01.86a404f3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[2129],{2845:s=>{s.exports=JSON.parse('{"label":"first","permalink":"/ppl-docs/blog/tags/first","allTagsPath":"/ppl-docs/blog/tags","count":1,"unlisted":false}')}}]); \ No newline at end of file diff --git a/assets/js/bde67976.326724d7.js b/assets/js/bde67976.326724d7.js new file mode 100644 index 0000000..5293456 --- /dev/null +++ b/assets/js/bde67976.326724d7.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[3619],{9950:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>c,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>a});var s=i(4848),t=i(8453);const r={sidebar_position:3},o="Sound files",l={id:"File Information/sound-files",title:"Sound files",description:"Example of a file that defines a single sound:",source:"@site/docs/File Information/sound-files.md",sourceDirName:"File Information",slug:"/File Information/sound-files",permalink:"/ppl-docs/docs/File Information/sound-files",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/File Information/sound-files.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Mesh files",permalink:"/ppl-docs/docs/File Information/mesh-files"},next:{title:"Beginner Lua Tutorial",permalink:"/ppl-docs/docs/Guides/Lua/beginner"}},c={},a=[];function u(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"sound-files",children:"Sound files"}),"\n",(0,s.jsx)(n.p,{children:"Example of a file that defines a single sound:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-lua",children:'sounds = {\n {\n frequency = 500,\n sustain = 0.3,\n waveform = "triangle",\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"The following fields can be used to describe a sound:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"attack (in seconds)"}),"\n",(0,s.jsx)(n.li,{children:"decay (in seconds)"}),"\n",(0,s.jsx)(n.li,{children:"sustain (in seconds)"}),"\n",(0,s.jsx)(n.li,{children:"sustainPunch (in seconds)"}),"\n",(0,s.jsx)(n.li,{children:"amplification"}),"\n",(0,s.jsx)(n.li,{children:"tremoloDepth"}),"\n",(0,s.jsx)(n.li,{children:"tremoloFrequency (in hertz)"}),"\n",(0,s.jsx)(n.li,{children:"frequency (in hertz)"}),"\n",(0,s.jsx)(n.li,{children:"frequencyDeltaSweep"}),"\n",(0,s.jsx)(n.li,{children:"frequencyJump1Onset"}),"\n",(0,s.jsx)(n.li,{children:"frequencyJump2Onset"}),"\n",(0,s.jsx)(n.li,{children:"frequencyJump1Amount"}),"\n",(0,s.jsx)(n.li,{children:"frequencyJump2Amount"}),"\n",(0,s.jsx)(n.li,{children:"frequencySweep"}),"\n",(0,s.jsx)(n.li,{children:"vibratoFrequency (in hertz)"}),"\n",(0,s.jsx)(n.li,{children:"vibratoDepth (in hertz)"}),"\n",(0,s.jsx)(n.li,{children:"flangerOffset"}),"\n",(0,s.jsx)(n.li,{children:"flangerOffsetSweep"}),"\n",(0,s.jsx)(n.li,{children:"repeatFrequency"}),"\n",(0,s.jsx)(n.li,{children:'waveform ("sine", "triangle", "sawtooth", "square", "tangent", "whistle", "breaker", "whitenoise", "pinknoise", "brownnoise")'}),"\n"]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["Use ",(0,s.jsx)(n.a,{href:"https://pewpew.live/jfxr/index.html",children:"jfxr"})," for sound creation. A script then transforms the resulting jfxr link (for example ",(0,s.jsx)(n.a,{href:"https://pewpew.live/jfxr/index.html#%7B%22_version%22%3A1%2C%22_name%22%3A%22Pickup%2Fcoin%206%22%2C%22_locked%22%3A%5B%5D%2C%22sampleRate%22%3A44100%2C%22attack%22%3A0%2C%22sustain%22%3A0.1%2C%22sustainPunch%22%3A60%2C%22decay%22%3A0.14%2C%22tremoloDepth%22%3A0%2C%22tremoloFrequency%22%3A10%2C%22frequency%22%3A700%2C%22frequencySweep%22%3A0%2C%22frequencyDeltaSweep%22%3A0%2C%22repeatFrequency%22%3A0%2C%22frequencyJump1Onset%22%3A25%2C%22frequencyJump1Amount%22%3A75%2C%22frequencyJump2Onset%22%3A66%2C%22frequencyJump2Amount%22%3A0%2C%22harmonics%22%3A0%2C%22harmonicsFalloff%22%3A0.5%2C%22waveform%22%3A%22square%22%2C%22interpolateNoise%22%3Atrue%2C%22vibratoDepth%22%3A0%2C%22vibratoFrequency%22%3A10%2C%22squareDuty%22%3A90%2C%22squareDutySweep%22%3A0%2C%22flangerOffset%22%3A6%2C%22flangerOffsetSweep%22%3A0%2C%22bitCrush%22%3A16%2C%22bitCrushSweep%22%3A0%2C%22lowPassCutoff%22%3A22050%2C%22lowPassCutoffSweep%22%3A0%2C%22highPassCutoff%22%3A0%2C%22highPassCutoffSweep%22%3A0%2C%22compression%22%3A1%2C%22normalization%22%3Atrue%2C%22amplification%22%3A100%7D",children:"this link"}),") into a table consumable by PewPew Live. See this ",(0,s.jsx)(n.a,{href:"https://github.com/jyaif/ppl-utils/blob/cd0607d3448915319ce9abc1f6019287566f6bdd/content/levels/useful_helpers/helpers/boxes/cannon_pickup_sound.lua#L3",children:"example"}),"."]})})]})}function d(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>l});var s=i(6540);const t={},r=s.createContext(t);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/bde67976.5934ae8a.js b/assets/js/bde67976.5934ae8a.js deleted file mode 100644 index 9e0a104..0000000 --- a/assets/js/bde67976.5934ae8a.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[3619],{9950:(e,n,i)=>{i.r(n),i.d(n,{assets:()=>a,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var s=i(4848),t=i(8453);const r={sidebar_position:3},o="Sound files",l={id:"File Information/sound-files",title:"Sound files",description:"Example of a file that defines a single sound:",source:"@site/docs/File Information/sound-files.md",sourceDirName:"File Information",slug:"/File Information/sound-files",permalink:"/docs/File Information/sound-files",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/File Information/sound-files.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Mesh files",permalink:"/docs/File Information/mesh-files"},next:{title:"Beginner Lua Tutorial",permalink:"/docs/Guides/Lua/beginner"}},a={},c=[];function u(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",li:"li",p:"p",pre:"pre",ul:"ul",...(0,t.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(n.h1,{id:"sound-files",children:"Sound files"}),"\n",(0,s.jsx)(n.p,{children:"Example of a file that defines a single sound:"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-lua",children:'sounds = {\n {\n frequency = 500,\n sustain = 0.3,\n waveform = "triangle",\n }\n}\n'})}),"\n",(0,s.jsx)(n.p,{children:"The following fields can be used to describe a sound:"}),"\n",(0,s.jsxs)(n.ul,{children:["\n",(0,s.jsx)(n.li,{children:"attack (in seconds)"}),"\n",(0,s.jsx)(n.li,{children:"decay (in seconds)"}),"\n",(0,s.jsx)(n.li,{children:"sustain (in seconds)"}),"\n",(0,s.jsx)(n.li,{children:"sustainPunch (in seconds)"}),"\n",(0,s.jsx)(n.li,{children:"amplification"}),"\n",(0,s.jsx)(n.li,{children:"tremoloDepth"}),"\n",(0,s.jsx)(n.li,{children:"tremoloFrequency (in hertz)"}),"\n",(0,s.jsx)(n.li,{children:"frequency (in hertz)"}),"\n",(0,s.jsx)(n.li,{children:"frequencyDeltaSweep"}),"\n",(0,s.jsx)(n.li,{children:"frequencyJump1Onset"}),"\n",(0,s.jsx)(n.li,{children:"frequencyJump2Onset"}),"\n",(0,s.jsx)(n.li,{children:"frequencyJump1Amount"}),"\n",(0,s.jsx)(n.li,{children:"frequencyJump2Amount"}),"\n",(0,s.jsx)(n.li,{children:"frequencySweep"}),"\n",(0,s.jsx)(n.li,{children:"vibratoFrequency (in hertz)"}),"\n",(0,s.jsx)(n.li,{children:"vibratoDepth (in hertz)"}),"\n",(0,s.jsx)(n.li,{children:"flangerOffset"}),"\n",(0,s.jsx)(n.li,{children:"flangerOffsetSweep"}),"\n",(0,s.jsx)(n.li,{children:"repeatFrequency"}),"\n",(0,s.jsx)(n.li,{children:'waveform ("sine", "triangle", "sawtooth", "square", "tangent", "whistle", "breaker", "whitenoise", "pinknoise", "brownnoise")'}),"\n"]}),"\n",(0,s.jsx)(n.admonition,{type:"tip",children:(0,s.jsxs)(n.p,{children:["Use ",(0,s.jsx)(n.a,{href:"https://pewpew.live/jfxr/index.html",children:"jfxr"})," for sound creation. A script then transforms the resulting jfxr link (for example ",(0,s.jsx)(n.a,{href:"https://pewpew.live/jfxr/index.html#%7B%22_version%22%3A1%2C%22_name%22%3A%22Pickup%2Fcoin%206%22%2C%22_locked%22%3A%5B%5D%2C%22sampleRate%22%3A44100%2C%22attack%22%3A0%2C%22sustain%22%3A0.1%2C%22sustainPunch%22%3A60%2C%22decay%22%3A0.14%2C%22tremoloDepth%22%3A0%2C%22tremoloFrequency%22%3A10%2C%22frequency%22%3A700%2C%22frequencySweep%22%3A0%2C%22frequencyDeltaSweep%22%3A0%2C%22repeatFrequency%22%3A0%2C%22frequencyJump1Onset%22%3A25%2C%22frequencyJump1Amount%22%3A75%2C%22frequencyJump2Onset%22%3A66%2C%22frequencyJump2Amount%22%3A0%2C%22harmonics%22%3A0%2C%22harmonicsFalloff%22%3A0.5%2C%22waveform%22%3A%22square%22%2C%22interpolateNoise%22%3Atrue%2C%22vibratoDepth%22%3A0%2C%22vibratoFrequency%22%3A10%2C%22squareDuty%22%3A90%2C%22squareDutySweep%22%3A0%2C%22flangerOffset%22%3A6%2C%22flangerOffsetSweep%22%3A0%2C%22bitCrush%22%3A16%2C%22bitCrushSweep%22%3A0%2C%22lowPassCutoff%22%3A22050%2C%22lowPassCutoffSweep%22%3A0%2C%22highPassCutoff%22%3A0%2C%22highPassCutoffSweep%22%3A0%2C%22compression%22%3A1%2C%22normalization%22%3Atrue%2C%22amplification%22%3A100%7D",children:"this link"}),") into a table consumable by PewPew Live. See this ",(0,s.jsx)(n.a,{href:"https://github.com/jyaif/ppl-utils/blob/cd0607d3448915319ce9abc1f6019287566f6bdd/content/levels/useful_helpers/helpers/boxes/cannon_pickup_sound.lua#L3",children:"example"}),"."]})})]})}function d(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(u,{...e})}):u(e)}},8453:(e,n,i)=>{i.d(n,{R:()=>o,x:()=>l});var s=i(6540);const t={},r=s.createContext(t);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(t):e.components||t:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c5039d34.1f98e805.js b/assets/js/c5039d34.1f98e805.js new file mode 100644 index 0000000..ef2f574 --- /dev/null +++ b/assets/js/c5039d34.1f98e805.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[8538],{1287:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>a,contentTitle:()=>d,default:()=>o,frontMatter:()=>s,metadata:()=>c,toc:()=>h});var l=n(4848),r=n(8453);const s={sidebar_position:3},d="Standard libraries",c={id:"APIs/standard-libraries",title:"Standard libraries",description:"Only a subset of the standard Lua libraries are available in PewPew Live:",source:"@site/docs/APIs/standard-libraries.md",sourceDirName:"APIs",slug:"/APIs/standard-libraries",permalink:"/ppl-docs/docs/APIs/standard-libraries",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/APIs/standard-libraries.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Fmath",permalink:"/ppl-docs/docs/APIs/Fmath"},next:{title:"Manifest files",permalink:"/ppl-docs/docs/File Information/manifest-files"}},a={},h=[{value:"String library",id:"string-library",level:2},{value:"Table library",id:"table-library",level:2},{value:"Math library",id:"math-library",level:2}];function t(e){const i={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(i.h1,{id:"standard-libraries",children:"Standard libraries"}),"\n",(0,l.jsxs)(i.p,{children:["Only a subset of the standard Lua libraries are available in PewPew Live:\nThe ",(0,l.jsx)(i.a,{href:"https://github.com/jyaif/ppl-utils/wiki/API_standard_lua_libs#string-library",children:"string"})," library, the ",(0,l.jsx)(i.a,{href:"https://github.com/jyaif/ppl-utils/wiki/API_standard_lua_libs#table-library",children:"table"})," library, and (for meshes and sound effects only) the ",(0,l.jsx)(i.a,{href:"https://github.com/jyaif/ppl-utils/wiki/API_standard_lua_libs#math-library",children:"math"})," library."]}),"\n",(0,l.jsx)(i.admonition,{type:"info",children:(0,l.jsx)(i.p,{children:"Level files do not have access to the math library. Use fmath instead."})}),"\n",(0,l.jsx)(i.h2,{id:"string-library",children:"String library"}),"\n",(0,l.jsx)(i.p,{children:"The library exposes the following functions:"}),"\n",(0,l.jsxs)(i.ul,{children:["\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"byte"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"char"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"dump"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"find"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"format"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"gmatch"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"gsub"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"len"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"lower"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"match"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"rep"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"reverse"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"sub"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"upper"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"pack"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"packsize"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"unpack"})}),"\n"]}),"\n",(0,l.jsxs)(i.p,{children:["The official Lua website has the ",(0,l.jsx)(i.a,{href:"https://www.lua.org/manual/5.3/manual.html#6.4",children:"documentation"})," for the string library."]}),"\n",(0,l.jsx)(i.h2,{id:"table-library",children:"Table library"}),"\n",(0,l.jsx)(i.p,{children:"The library exposes the following functions:"}),"\n",(0,l.jsxs)(i.ul,{children:["\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"concat"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"insert"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"pack"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"unpack"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"remove"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"move"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"sort"})}),"\n"]}),"\n",(0,l.jsxs)(i.p,{children:["The official Lua website has the ",(0,l.jsx)(i.a,{href:"https://www.lua.org/manual/5.3/manual.html#6.6",children:"documentation"})," for the table library."]}),"\n",(0,l.jsx)(i.h2,{id:"math-library",children:"Math library"}),"\n",(0,l.jsxs)(i.p,{children:["The Lua ",(0,l.jsx)(i.code,{children:"math"})," library is only available for meshes and sound effects.\nIt is not available when creating levels because the functions it offer are often for dealing with floating point numbers."]}),"\n",(0,l.jsx)(i.p,{children:"The library exposes the following functions:"}),"\n",(0,l.jsxs)(i.ul,{children:["\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"abs"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"acos"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"asin"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"atan"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"ceil"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"cos"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"deg"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"exp"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"tointeger"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"floor"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"fmod"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"ult"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"log"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"max"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"min"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"modf"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"rad"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"random"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"sin"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"sincos"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"sqrt"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"tan"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"type"})}),"\n"]}),"\n",(0,l.jsx)(i.p,{children:"and the constants:"}),"\n",(0,l.jsxs)(i.ul,{children:["\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"pi"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"huge"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"maxinteger"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"mininteger"})}),"\n"]}),"\n",(0,l.jsxs)(i.p,{children:["The only absent API is ",(0,l.jsx)(i.code,{children:"randomseed"})," (the RNG is already seeded with a good seed).\nIf you need a predictable random sequence, use your own RNG implemented in Lua."]}),"\n",(0,l.jsxs)(i.p,{children:["The official Lua website has the ",(0,l.jsx)(i.a,{href:"https://www.lua.org/manual/5.3/manual.html#6.7",children:"documentation"})," for the math library."]})]})}function o(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,l.jsx)(i,{...e,children:(0,l.jsx)(t,{...e})}):t(e)}},8453:(e,i,n)=>{n.d(i,{R:()=>d,x:()=>c});var l=n(6540);const r={},s=l.createContext(r);function d(e){const i=l.useContext(s);return l.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function c(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),l.createElement(s.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c5039d34.73855edb.js b/assets/js/c5039d34.73855edb.js deleted file mode 100644 index b1736ef..0000000 --- a/assets/js/c5039d34.73855edb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[8538],{1287:(e,i,n)=>{n.r(i),n.d(i,{assets:()=>a,contentTitle:()=>d,default:()=>o,frontMatter:()=>s,metadata:()=>c,toc:()=>h});var l=n(4848),r=n(8453);const s={sidebar_position:3},d="Standard libraries",c={id:"APIs/standard-libraries",title:"Standard libraries",description:"Only a subset of the standard Lua libraries are available in PewPew Live:",source:"@site/docs/APIs/standard-libraries.md",sourceDirName:"APIs",slug:"/APIs/standard-libraries",permalink:"/docs/APIs/standard-libraries",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/APIs/standard-libraries.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Fmath",permalink:"/docs/APIs/Fmath"},next:{title:"Manifest files",permalink:"/docs/File Information/manifest-files"}},a={},h=[{value:"String library",id:"string-library",level:2},{value:"Table library",id:"table-library",level:2},{value:"Math library",id:"math-library",level:2}];function t(e){const i={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",li:"li",p:"p",ul:"ul",...(0,r.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(i.h1,{id:"standard-libraries",children:"Standard libraries"}),"\n",(0,l.jsxs)(i.p,{children:["Only a subset of the standard Lua libraries are available in PewPew Live:\nThe ",(0,l.jsx)(i.a,{href:"https://github.com/jyaif/ppl-utils/wiki/API_standard_lua_libs#string-library",children:"string"})," library, the ",(0,l.jsx)(i.a,{href:"https://github.com/jyaif/ppl-utils/wiki/API_standard_lua_libs#table-library",children:"table"})," library, and (for meshes and sound effects only) the ",(0,l.jsx)(i.a,{href:"https://github.com/jyaif/ppl-utils/wiki/API_standard_lua_libs#math-library",children:"math"})," library."]}),"\n",(0,l.jsx)(i.admonition,{type:"info",children:(0,l.jsx)(i.p,{children:"Level files do not have access to the math library. Use fmath instead."})}),"\n",(0,l.jsx)(i.h2,{id:"string-library",children:"String library"}),"\n",(0,l.jsx)(i.p,{children:"The library exposes the following functions:"}),"\n",(0,l.jsxs)(i.ul,{children:["\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"byte"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"char"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"dump"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"find"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"format"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"gmatch"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"gsub"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"len"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"lower"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"match"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"rep"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"reverse"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"sub"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"upper"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"pack"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"packsize"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"unpack"})}),"\n"]}),"\n",(0,l.jsxs)(i.p,{children:["The official Lua website has the ",(0,l.jsx)(i.a,{href:"https://www.lua.org/manual/5.3/manual.html#6.4",children:"documentation"})," for the string library."]}),"\n",(0,l.jsx)(i.h2,{id:"table-library",children:"Table library"}),"\n",(0,l.jsx)(i.p,{children:"The library exposes the following functions:"}),"\n",(0,l.jsxs)(i.ul,{children:["\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"concat"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"insert"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"pack"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"unpack"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"remove"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"move"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"sort"})}),"\n"]}),"\n",(0,l.jsxs)(i.p,{children:["The official Lua website has the ",(0,l.jsx)(i.a,{href:"https://www.lua.org/manual/5.3/manual.html#6.6",children:"documentation"})," for the table library."]}),"\n",(0,l.jsx)(i.h2,{id:"math-library",children:"Math library"}),"\n",(0,l.jsxs)(i.p,{children:["The Lua ",(0,l.jsx)(i.code,{children:"math"})," library is only available for meshes and sound effects.\nIt is not available when creating levels because the functions it offer are often for dealing with floating point numbers."]}),"\n",(0,l.jsx)(i.p,{children:"The library exposes the following functions:"}),"\n",(0,l.jsxs)(i.ul,{children:["\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"abs"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"acos"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"asin"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"atan"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"ceil"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"cos"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"deg"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"exp"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"tointeger"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"floor"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"fmod"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"ult"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"log"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"max"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"min"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"modf"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"rad"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"random"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"sin"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"sincos"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"sqrt"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"tan"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"type"})}),"\n"]}),"\n",(0,l.jsx)(i.p,{children:"and the constants:"}),"\n",(0,l.jsxs)(i.ul,{children:["\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"pi"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"huge"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"maxinteger"})}),"\n",(0,l.jsx)(i.li,{children:(0,l.jsx)(i.code,{children:"mininteger"})}),"\n"]}),"\n",(0,l.jsxs)(i.p,{children:["The only absent API is ",(0,l.jsx)(i.code,{children:"randomseed"})," (the RNG is already seeded with a good seed).\nIf you need a predictable random sequence, use your own RNG implemented in Lua."]}),"\n",(0,l.jsxs)(i.p,{children:["The official Lua website has the ",(0,l.jsx)(i.a,{href:"https://www.lua.org/manual/5.3/manual.html#6.7",children:"documentation"})," for the math library."]})]})}function o(e={}){const{wrapper:i}={...(0,r.R)(),...e.components};return i?(0,l.jsx)(i,{...e,children:(0,l.jsx)(t,{...e})}):t(e)}},8453:(e,i,n)=>{n.d(i,{R:()=>d,x:()=>c});var l=n(6540);const r={},s=l.createContext(r);function d(e){const i=l.useContext(s);return l.useMemo((function(){return"function"==typeof e?e(i):{...i,...e}}),[i,e])}function c(e){let i;return i=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:d(e.components),l.createElement(s.Provider,{value:i},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c9cd16d1.15d0e772.js b/assets/js/c9cd16d1.15d0e772.js deleted file mode 100644 index 584fd6f..0000000 --- a/assets/js/c9cd16d1.15d0e772.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[1414],{637:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>s,default:()=>u,frontMatter:()=>o,metadata:()=>r,toc:()=>c});var a=n(4848),i=n(8453);const o={sidebar_position:3},s="Advanced",r={id:"Guides/Lua/advanced",title:"Advanced",description:"In this tutorial, we will learn how to make more advanced levels, including meshes, custom enemies, and other cool gameplay features!",source:"@site/docs/Guides/Lua/advanced.md",sourceDirName:"Guides/Lua",slug:"/Guides/Lua/advanced",permalink:"/docs/Guides/Lua/advanced",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/Guides/Lua/advanced.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Intermediate",permalink:"/docs/Guides/Lua/intermediate"},next:{title:"60 FPS Animation",permalink:"/docs/Guides/Other/fps-animation"}},d={},c=[{value:"Note",id:"note",level:3}];function l(e){const t={h1:"h1",h3:"h3",hr:"hr",p:"p",...(0,i.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(t.h1,{id:"advanced",children:"Advanced"}),"\n",(0,a.jsx)(t.p,{children:"In this tutorial, we will learn how to make more advanced levels, including meshes, custom enemies, and other cool gameplay features!"}),"\n",(0,a.jsx)(t.p,{children:"So, let's get straight into it."}),"\n",(0,a.jsx)(t.hr,{}),"\n",(0,a.jsx)(t.h3,{id:"note",children:"Note"}),"\n",(0,a.jsx)(t.p,{children:"Before we start, it is necessary to know at least some basic Lua and how to make a simple PewPew Live level. If you need a refresher, take a look at the Beginner and Intermediate tutorials."}),"\n",(0,a.jsx)(t.p,{children:"Once you're done, you can come back to this tutorial."}),"\n",(0,a.jsx)(t.hr,{}),"\n",(0,a.jsx)(t.p,{children:"Tutorial in the making."})]})}function u(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(l,{...e})}):l(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>s,x:()=>r});var a=n(6540);const i={},o=a.createContext(i);function s(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c9cd16d1.ccdfc422.js b/assets/js/c9cd16d1.ccdfc422.js new file mode 100644 index 0000000..872ba76 --- /dev/null +++ b/assets/js/c9cd16d1.ccdfc422.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[1414],{637:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>d,contentTitle:()=>i,default:()=>u,frontMatter:()=>a,metadata:()=>r,toc:()=>c});var o=n(4848),s=n(8453);const a={sidebar_position:3},i="Advanced",r={id:"Guides/Lua/advanced",title:"Advanced",description:"In this tutorial, we will learn how to make more advanced levels, including meshes, custom enemies, and other cool gameplay features!",source:"@site/docs/Guides/Lua/advanced.md",sourceDirName:"Guides/Lua",slug:"/Guides/Lua/advanced",permalink:"/ppl-docs/docs/Guides/Lua/advanced",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/Guides/Lua/advanced.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{sidebar_position:3},sidebar:"tutorialSidebar",previous:{title:"Intermediate",permalink:"/ppl-docs/docs/Guides/Lua/intermediate"},next:{title:"60 FPS Animation",permalink:"/ppl-docs/docs/Guides/Other/fps-animation"}},d={},c=[{value:"Note",id:"note",level:3}];function l(e){const t={h1:"h1",h3:"h3",hr:"hr",p:"p",...(0,s.R)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(t.h1,{id:"advanced",children:"Advanced"}),"\n",(0,o.jsx)(t.p,{children:"In this tutorial, we will learn how to make more advanced levels, including meshes, custom enemies, and other cool gameplay features!"}),"\n",(0,o.jsx)(t.p,{children:"So, let's get straight into it."}),"\n",(0,o.jsx)(t.hr,{}),"\n",(0,o.jsx)(t.h3,{id:"note",children:"Note"}),"\n",(0,o.jsx)(t.p,{children:"Before we start, it is necessary to know at least some basic Lua and how to make a simple PewPew Live level. If you need a refresher, take a look at the Beginner and Intermediate tutorials."}),"\n",(0,o.jsx)(t.p,{children:"Once you're done, you can come back to this tutorial."}),"\n",(0,o.jsx)(t.hr,{}),"\n",(0,o.jsx)(t.p,{children:"Tutorial in the making."})]})}function u(e={}){const{wrapper:t}={...(0,s.R)(),...e.components};return t?(0,o.jsx)(t,{...e,children:(0,o.jsx)(l,{...e})}):l(e)}},8453:(e,t,n)=>{n.d(t,{R:()=>i,x:()=>r});var o=n(6540);const s={},a=o.createContext(s);function i(e){const t=o.useContext(a);return o.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function r(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:i(e.components),o.createElement(a.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c9e852ed.433dbfc2.js b/assets/js/c9e852ed.433dbfc2.js new file mode 100644 index 0000000..46e888f --- /dev/null +++ b/assets/js/c9e852ed.433dbfc2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[9630],{819:e=>{e.exports=JSON.parse('{"blogPosts":[{"id":"first-blog-post","metadata":{"permalink":"/ppl-docs/blog/first-blog-post","source":"@site/blog/2024-03-20-first-blog-post.md","title":"First Blog Post","description":"Welcome to the first blog article! We are so excited to move the entirety of PPL level development documentation here. This platform allows us to make more interactive (via React components), good looking documentation and having powerful search!","date":"2024-03-20T00:00:00.000Z","formattedDate":"March 20, 2024","tags":[{"label":"first","permalink":"/ppl-docs/blog/tags/first"}],"readingTime":0.245,"hasTruncateMarker":false,"authors":[{"name":"Dominykas M.","title":"PewPew Live developer and creator of PPL Docs","url":"https://tastykiwi.omg.lol/","imageURL":"https://github.com/Tasty-Kiwi.png","key":"tastykiwi"}],"frontMatter":{"slug":"first-blog-post","title":"First Blog Post","authors":"tastykiwi","tags":["first"]},"unlisted":false},"content":"Welcome to the first blog article! We are so excited to move the entirety of PPL level development documentation here. This platform allows us to make more interactive (via React components), good looking documentation and having powerful search!\\n\\nI hope you\'ll like the new home for PewPew docs.\\n\\nEnjoy!"}]}')}}]); \ No newline at end of file diff --git a/assets/js/cd2705ba.af492360.js b/assets/js/cd2705ba.af492360.js new file mode 100644 index 0000000..eda52be --- /dev/null +++ b/assets/js/cd2705ba.af492360.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[1341],{328:p=>{p.exports=JSON.parse('{"permalink":"/ppl-docs/blog","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/d321bdfd.324af267.js b/assets/js/d321bdfd.324af267.js deleted file mode 100644 index 9af8aeb..0000000 --- a/assets/js/d321bdfd.324af267.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[4387],{676:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>o,default:()=>f,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var t=n(4848),i=n(8453);const r={sidebar_position:2},o="Mesh files",l={id:"File Information/mesh-files",title:"Mesh files",description:"In PewPew Live, a mesh is a collection of lines in 3D.",source:"@site/docs/File Information/mesh-files.md",sourceDirName:"File Information",slug:"/File Information/mesh-files",permalink:"/docs/File Information/mesh-files",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/File Information/mesh-files.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Manifest files",permalink:"/docs/File Information/manifest-files"},next:{title:"Sound files",permalink:"/docs/File Information/sound-files"}},a={},c=[{value:"Vertexes",id:"vertexes",level:2},{value:"Segments chains",id:"segments-chains",level:2},{value:"Colors",id:"colors",level:2},{value:"Procedural rendering",id:"procedural-rendering",level:2}];function d(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.h1,{id:"mesh-files",children:"Mesh files"}),"\n",(0,t.jsxs)(s.p,{children:["In PewPew Live, a mesh is a collection of lines in 3D.\nTo create a mesh, you need to list the coordinates of the points making up the model, and how the points are linked.\nLua scripts describing meshes needs to create a table called ",(0,t.jsx)(s.code,{children:"meshes"}),". That table must contain one or more meshes."]}),"\n",(0,t.jsx)(s.p,{children:"Example of a file that defines two meshes:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-lua",children:"meshes = {\n { -- A 500x500 square\n vertexes = {{0,0,0}, {500,0,0}, {500,500,0}, {0,500,0}},\n colors = {0xffffffff, 0xffff00ff, 0xff00ffff, 0xff0000ff},\n segments = {{0,1,2,3,0}}\n },\n { -- A right-angled triangle\n vertexes = {{0,0,0}, {500,0,0}, {0,500,0}},\n colors = {0xffff00ff, 0xff00ffff, 0xff0000ff},\n segments = {{0,1,2,0}}\n }\n}\n"})}),"\n",(0,t.jsx)(s.h2,{id:"vertexes",children:"Vertexes"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.code,{children:"vertexes"})," field contains the list of vertexes. Vertexes are represented by three numbers. Those numbers can be floating point numbers."]}),"\n",(0,t.jsx)(s.h2,{id:"segments-chains",children:"Segments chains"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.code,{children:"segment"})," field describes which vertexes should be joined by a segment. It contain a list of segment chains. Each segment chain is a table that holds a lists of 0-based indexes to vertexes that should be connected by a segment."]}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.strong,{children:"Important"}),": There is a difference between ",(0,t.jsx)(s.code,{children:"segments = {{0,1}, {1,2}}"})," and ",(0,t.jsx)(s.code,{children:"segments = {{0,1,2}}"}),". In the first case, 2 separate segments will be generated. In the second case, two segments linked with a miter join will be generated."]}),"\n",(0,t.jsx)(s.h2,{id:"colors",children:"Colors"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.em,{children:"optional"})," ",(0,t.jsx)(s.code,{children:"colors"})," field contains the colors of each vertexes. If the ",(0,t.jsx)(s.code,{children:"colors"})," field is present, it ",(0,t.jsx)(s.strong,{children:"must"})," contain as many colors as there are vertexes. Colors are 32 bit RGBA values."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-lua",children:"0xff0000ff -- opaque red\n0xff000080 -- slightly transparent red\n0xff000000 -- fully transparent red\n"})}),"\n",(0,t.jsx)(s.p,{children:"Note that all meshes are rendered with additive blending."}),"\n",(0,t.jsx)(s.h2,{id:"procedural-rendering",children:"Procedural rendering"}),"\n",(0,t.jsxs)(s.p,{children:["Astute readers may have realized that because ",(0,t.jsx)(s.code,{children:"meshes"})," is described in a Lua script, it can be generated at runtime. See for instance this ",(0,t.jsx)(s.a,{href:"https://github.com/jyaif/ppl-utils/blob/d32dbec8a171c9bcc0f800dcd864f175c42c34fd/content/levels/advanced_graphics/polar_graphic.lua#L36",children:"example"}),"."]})]})}function f(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},8453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>l});var t=n(6540);const i={},r=t.createContext(i);function o(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d321bdfd.707b2e80.js b/assets/js/d321bdfd.707b2e80.js new file mode 100644 index 0000000..fba01c1 --- /dev/null +++ b/assets/js/d321bdfd.707b2e80.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[4387],{676:(e,s,n)=>{n.r(s),n.d(s,{assets:()=>a,contentTitle:()=>o,default:()=>f,frontMatter:()=>r,metadata:()=>l,toc:()=>c});var t=n(4848),i=n(8453);const r={sidebar_position:2},o="Mesh files",l={id:"File Information/mesh-files",title:"Mesh files",description:"In PewPew Live, a mesh is a collection of lines in 3D.",source:"@site/docs/File Information/mesh-files.md",sourceDirName:"File Information",slug:"/File Information/mesh-files",permalink:"/ppl-docs/docs/File Information/mesh-files",draft:!1,unlisted:!1,editUrl:"https://github.com/pewpewlive/ppl-docs/edit/master/docs/File Information/mesh-files.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{sidebar_position:2},sidebar:"tutorialSidebar",previous:{title:"Manifest files",permalink:"/ppl-docs/docs/File Information/manifest-files"},next:{title:"Sound files",permalink:"/ppl-docs/docs/File Information/sound-files"}},a={},c=[{value:"Vertexes",id:"vertexes",level:2},{value:"Segments chains",id:"segments-chains",level:2},{value:"Colors",id:"colors",level:2},{value:"Procedural rendering",id:"procedural-rendering",level:2}];function d(e){const s={a:"a",code:"code",em:"em",h1:"h1",h2:"h2",p:"p",pre:"pre",strong:"strong",...(0,i.R)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(s.h1,{id:"mesh-files",children:"Mesh files"}),"\n",(0,t.jsxs)(s.p,{children:["In PewPew Live, a mesh is a collection of lines in 3D.\nTo create a mesh, you need to list the coordinates of the points making up the model, and how the points are linked.\nLua scripts describing meshes needs to create a table called ",(0,t.jsx)(s.code,{children:"meshes"}),". That table must contain one or more meshes."]}),"\n",(0,t.jsx)(s.p,{children:"Example of a file that defines two meshes:"}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-lua",children:"meshes = {\n { -- A 500x500 square\n vertexes = {{0,0,0}, {500,0,0}, {500,500,0}, {0,500,0}},\n colors = {0xffffffff, 0xffff00ff, 0xff00ffff, 0xff0000ff},\n segments = {{0,1,2,3,0}}\n },\n { -- A right-angled triangle\n vertexes = {{0,0,0}, {500,0,0}, {0,500,0}},\n colors = {0xffff00ff, 0xff00ffff, 0xff0000ff},\n segments = {{0,1,2,0}}\n }\n}\n"})}),"\n",(0,t.jsx)(s.h2,{id:"vertexes",children:"Vertexes"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.code,{children:"vertexes"})," field contains the list of vertexes. Vertexes are represented by three numbers. Those numbers can be floating point numbers."]}),"\n",(0,t.jsx)(s.h2,{id:"segments-chains",children:"Segments chains"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.code,{children:"segment"})," field describes which vertexes should be joined by a segment. It contain a list of segment chains. Each segment chain is a table that holds a lists of 0-based indexes to vertexes that should be connected by a segment."]}),"\n",(0,t.jsxs)(s.p,{children:[(0,t.jsx)(s.strong,{children:"Important"}),": There is a difference between ",(0,t.jsx)(s.code,{children:"segments = {{0,1}, {1,2}}"})," and ",(0,t.jsx)(s.code,{children:"segments = {{0,1,2}}"}),". In the first case, 2 separate segments will be generated. In the second case, two segments linked with a miter join will be generated."]}),"\n",(0,t.jsx)(s.h2,{id:"colors",children:"Colors"}),"\n",(0,t.jsxs)(s.p,{children:["The ",(0,t.jsx)(s.em,{children:"optional"})," ",(0,t.jsx)(s.code,{children:"colors"})," field contains the colors of each vertexes. If the ",(0,t.jsx)(s.code,{children:"colors"})," field is present, it ",(0,t.jsx)(s.strong,{children:"must"})," contain as many colors as there are vertexes. Colors are 32 bit RGBA values."]}),"\n",(0,t.jsx)(s.pre,{children:(0,t.jsx)(s.code,{className:"language-lua",children:"0xff0000ff -- opaque red\n0xff000080 -- slightly transparent red\n0xff000000 -- fully transparent red\n"})}),"\n",(0,t.jsx)(s.p,{children:"Note that all meshes are rendered with additive blending."}),"\n",(0,t.jsx)(s.h2,{id:"procedural-rendering",children:"Procedural rendering"}),"\n",(0,t.jsxs)(s.p,{children:["Astute readers may have realized that because ",(0,t.jsx)(s.code,{children:"meshes"})," is described in a Lua script, it can be generated at runtime. See for instance this ",(0,t.jsx)(s.a,{href:"https://github.com/jyaif/ppl-utils/blob/d32dbec8a171c9bcc0f800dcd864f175c42c34fd/content/levels/advanced_graphics/polar_graphic.lua#L36",children:"example"}),"."]})]})}function f(e={}){const{wrapper:s}={...(0,i.R)(),...e.components};return s?(0,t.jsx)(s,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},8453:(e,s,n)=>{n.d(s,{R:()=>o,x:()=>l});var t=n(6540);const i={},r=t.createContext(i);function o(e){const s=t.useContext(r);return t.useMemo((function(){return"function"==typeof e?e(s):{...s,...e}}),[s,e])}function l(e){let s;return s=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:o(e.components),t.createElement(r.Provider,{value:s},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/d86380de.5369d551.js b/assets/js/d86380de.5369d551.js new file mode 100644 index 0000000..7d3b301 --- /dev/null +++ b/assets/js/d86380de.5369d551.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[199],{8460:s=>{s.exports=JSON.parse('{"permalink":"/ppl-docs/blog/tags/first","page":1,"postsPerPage":10,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/d8d6d394.b5a6885d.js b/assets/js/d8d6d394.b5a6885d.js new file mode 100644 index 0000000..2375ee3 --- /dev/null +++ b/assets/js/d8d6d394.b5a6885d.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[7413],{5587:s=>{s.exports=JSON.parse('[{"label":"first","permalink":"/ppl-docs/blog/tags/first","count":1}]')}}]); \ No newline at end of file diff --git a/assets/js/main.344f4c73.js b/assets/js/main.344f4c73.js deleted file mode 100644 index da0bb2c..0000000 --- a/assets/js/main.344f4c73.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! For license information please see main.344f4c73.js.LICENSE.txt */ -(self.webpackChunkppl_docs=self.webpackChunkppl_docs||[]).push([[8792],{5391:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta});const a=function(){for(var e,t,n=0,a="";n{"use strict";n.d(t,{A:()=>f});n(6540);var r=n(3259),a=n.n(r),o=n(4054);const i={"01a85c17":[()=>Promise.all([n.e(1869),n.e(8209)]).then(n.bind(n,9158)),"@theme/BlogTagsListPage",9158],"0be36c6e":[()=>Promise.all([n.e(4132),n.e(5559)]).then(n.bind(n,6304)),"@site/docs/Guides/Other/60-fps-animation.mdx",6304],"0e384e19":[()=>n.e(3976).then(n.bind(n,1512)),"@site/docs/intro.md",1512],"0f881721":[()=>n.e(7810).then(n.bind(n,1580)),"@site/docs/other/trivia.md",1580],12193896:[()=>n.e(5088).then(n.bind(n,6592)),"@site/docs/other/level-design-principles.md",6592],17896441:[()=>Promise.all([n.e(1869),n.e(8222),n.e(8401)]).then(n.bind(n,5022)),"@theme/DocItem",5022],"1a4e3797":[()=>Promise.all([n.e(1869),n.e(2138)]).then(n.bind(n,1283)),"@theme/SearchPage",1283],"1df93b7f":[()=>Promise.all([n.e(1869),n.e(4583)]).then(n.bind(n,8198)),"@site/src/pages/index.tsx",8198],"3164f9fb":[()=>n.e(198).then(n.bind(n,8730)),"@site/docs/Guides/Lua/intermediate.md",8730],"3679e0b2":[()=>n.e(3151).then(n.bind(n,4988)),"@site/blog/2024-03-20-first-blog-post.md",4988],"4315fc58":[()=>n.e(7376).then(n.bind(n,2804)),"@site/docs/APIs/PewPew.md",2804],"46e25335":[()=>n.e(9612).then(n.bind(n,4212)),"@site/docs/File Information/manifest-files.md",4212],"59bfc863":[()=>n.e(2501).then(n.t.bind(n,2945,19)),"/home/runner/work/ppl-docs/ppl-docs/.docusaurus/docusaurus-plugin-content-blog/default/plugin-route-context-module-100.json",2945],"5e95c892":[()=>n.e(9647).then(n.bind(n,7121)),"@theme/DocsRoot",7121],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,4784)),"@generated/docusaurus.config",4784],"61036be0":[()=>n.e(2256).then(n.bind(n,1869)),"@site/docs/Guides/Lua/beginner.md",1869],"6875c492":[()=>Promise.all([n.e(1869),n.e(8222),n.e(8544),n.e(4813)]).then(n.bind(n,3069)),"@theme/BlogTagsPostsPage",3069],"693aa6a8":[()=>n.e(3194).then(n.bind(n,3305)),"@site/docs/other/level-restrictions.md",3305],"7370b24e":[()=>n.e(8573).then(n.t.bind(n,4061,19)),"/home/runner/work/ppl-docs/ppl-docs/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",4061],"7d528a0b":[()=>n.e(3736).then(n.bind(n,2520)),"@site/blog/2024-03-20-first-blog-post.md?truncated=true",2520],"814f3328":[()=>n.e(7472).then(n.t.bind(n,5513,19)),"~blog/default/blog-post-list-prop-default.json",5513],"91cb3e84":[()=>n.e(298).then(n.bind(n,7962)),"@site/docs/APIs/Fmath.md",7962],"935f2afb":[()=>n.e(8581).then(n.t.bind(n,5610,19)),"~docs/default/version-current-metadata-prop-751.json",5610],"9a119d2a":[()=>n.e(1387).then(n.t.bind(n,490,19)),"~blog/default/blog-tags-first-689.json",490],"9e4087bc":[()=>n.e(2711).then(n.bind(n,9331)),"@theme/BlogArchivePage",9331],a6aa9e1f:[()=>Promise.all([n.e(1869),n.e(8222),n.e(8544),n.e(7643)]).then(n.bind(n,7785)),"@theme/BlogListPage",7785],a7023ddc:[()=>n.e(9267).then(n.t.bind(n,8289,19)),"~blog/default/blog-tags-tags-4c2.json",8289],a7bd4aaa:[()=>n.e(7098).then(n.bind(n,4532)),"@theme/DocVersionRoot",4532],a94703ab:[()=>Promise.all([n.e(1869),n.e(9048)]).then(n.bind(n,2559)),"@theme/DocRoot",2559],b204be58:[()=>n.e(9363).then(n.bind(n,3621)),"@site/docs/APIs/types.mdx",3621],b2b675dd:[()=>n.e(1991).then(n.t.bind(n,9775,19)),"~blog/default/blog-c06.json",9775],b2f554cd:[()=>n.e(5894).then(n.t.bind(n,6042,19)),"~blog/default/blog-archive-80c.json",6042],b745e581:[()=>n.e(8064).then(n.t.bind(n,2705,19)),"~blog/default/blog-tags-first-689-list.json",2705],bde67976:[()=>n.e(3619).then(n.bind(n,9950)),"@site/docs/File Information/sound-files.md",9950],c5039d34:[()=>n.e(8538).then(n.bind(n,1287)),"@site/docs/APIs/standard-libraries.md",1287],c9cd16d1:[()=>n.e(1414).then(n.bind(n,637)),"@site/docs/Guides/Lua/advanced.md",637],ccc49370:[()=>Promise.all([n.e(1869),n.e(8222),n.e(8544),n.e(3249)]).then(n.bind(n,4029)),"@theme/BlogPostPage",4029],d321bdfd:[()=>n.e(4387).then(n.bind(n,676)),"@site/docs/File Information/mesh-files.md",676],f0258939:[()=>n.e(4123).then(n.t.bind(n,1966,19)),"/home/runner/work/ppl-docs/ppl-docs/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",1966],fe8ddc1f:[()=>n.e(5634).then(n.t.bind(n,1142,19)),"/home/runner/work/ppl-docs/ppl-docs/.docusaurus/@easyops-cn/docusaurus-search-local/default/plugin-route-context-module-100.json",1142]};var s=n(4848);function l(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,s.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,s.jsx)("p",{children:String(t)}),(0,s.jsx)("div",{children:(0,s.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,s.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,s.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,s.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,s.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var u=n(6921),c=n(3102);function d(e,t){if("*"===e)return a()({loading:l,loader:()=>n.e(2237).then(n.bind(n,2237)),modules:["@theme/NotFound"],webpack:()=>[2237],render(e,t){const n=e.default;return(0,s.jsx)(c.W,{value:{plugin:{name:"native",id:"default"}},children:(0,s.jsx)(n,{...t})})}});const r=o[`${e}-${t}`],d={},f=[],p=[],h=(0,u.A)(r);return Object.entries(h).forEach((e=>{let[t,n]=e;const r=i[n];r&&(d[t]=r[0],f.push(r[1]),p.push(r[2]))})),a().Map({loading:l,loader:d,modules:f,webpack:()=>p,render(t,n){const a=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const o=r.default;if(!o)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof o&&"function"!=typeof o||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{o[e]=r[e]}));let i=a;const s=n.split(".");s.slice(0,-1).forEach((e=>{i=i[e]})),i[s[s.length-1]]=o}));const o=a.__comp;delete a.__comp;const i=a.__context;return delete a.__context,(0,s.jsx)(c.W,{value:i,children:(0,s.jsx)(o,{...a,...n})})}})}const f=[{path:"/blog",component:d("/blog","ae9"),exact:!0},{path:"/blog/archive",component:d("/blog/archive","45b"),exact:!0},{path:"/blog/first-blog-post",component:d("/blog/first-blog-post","875"),exact:!0},{path:"/blog/tags",component:d("/blog/tags","663"),exact:!0},{path:"/blog/tags/first",component:d("/blog/tags/first","daf"),exact:!0},{path:"/search",component:d("/search","260"),exact:!0},{path:"/docs",component:d("/docs","4de"),routes:[{path:"/docs",component:d("/docs","109"),routes:[{path:"/docs",component:d("/docs","067"),routes:[{path:"/docs/APIs/Fmath",component:d("/docs/APIs/Fmath","f04"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/APIs/PewPew",component:d("/docs/APIs/PewPew","651"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/APIs/standard-libraries",component:d("/docs/APIs/standard-libraries","807"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/APIs/types",component:d("/docs/APIs/types","921"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/File Information/manifest-files",component:d("/docs/File Information/manifest-files","474"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/File Information/mesh-files",component:d("/docs/File Information/mesh-files","7e9"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/File Information/sound-files",component:d("/docs/File Information/sound-files","3a1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/Guides/Lua/advanced",component:d("/docs/Guides/Lua/advanced","493"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/Guides/Lua/beginner",component:d("/docs/Guides/Lua/beginner","848"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/Guides/Lua/intermediate",component:d("/docs/Guides/Lua/intermediate","fa2"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/Guides/Other/fps-animation",component:d("/docs/Guides/Other/fps-animation","5c1"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/intro",component:d("/docs/intro","aed"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/other/level-design-principles",component:d("/docs/other/level-design-principles","b5b"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/other/level-restrictions",component:d("/docs/other/level-restrictions","1b4"),exact:!0,sidebar:"tutorialSidebar"},{path:"/docs/other/trivia",component:d("/docs/other/trivia","8f5"),exact:!0,sidebar:"tutorialSidebar"}]}]}]},{path:"/",component:d("/","01a"),exact:!0},{path:"*",component:d("*")}]},6125:(e,t,n)=>{"use strict";n.d(t,{o:()=>o,x:()=>i});var r=n(6540),a=n(4848);const o=r.createContext(!1);function i(e){let{children:t}=e;const[n,i]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{i(!0)}),[]),(0,a.jsx)(o.Provider,{value:n,children:t})}},8536:(e,t,n)=>{"use strict";var r=n(6540),a=n(5338),o=n(4625),i=n(545),s=n(8193);const l=[n(119),n(6134),n(6294),n(1043)];var u=n(8328),c=n(6347),d=n(2831),f=n(4848);function p(e){let{children:t}=e;return(0,f.jsx)(f.Fragment,{children:t})}var h=n(5260),g=n(4586),m=n(6025),y=n(6342),b=n(1003),v=n(2131),w=n(4090),x=n(2967),k=n(440),S=n(1463);function E(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,g.A)(),r=(0,v.o)(),a=n[e].htmlLang,o=e=>e.replace("-","_");return(0,f.jsxs)(h.A,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,f.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,f.jsx)("meta",{property:"og:locale",content:o(a)}),Object.values(n).filter((e=>a!==e.htmlLang)).map((e=>(0,f.jsx)("meta",{property:"og:locale:alternate",content:o(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function _(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,g.A)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,g.A)(),{pathname:r}=(0,c.zy)();return e+(0,k.applyTrailingSlash)((0,m.A)(r),{trailingSlash:n,baseUrl:t})}(),a=t?`${n}${t}`:r;return(0,f.jsxs)(h.A,{children:[(0,f.jsx)("meta",{property:"og:url",content:a}),(0,f.jsx)("link",{rel:"canonical",href:a})]})}function C(){const{i18n:{currentLocale:e}}=(0,g.A)(),{metadata:t,image:n}=(0,y.p)();return(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(h.A,{children:[(0,f.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,f.jsx)("body",{className:w.w})]}),n&&(0,f.jsx)(b.be,{image:n}),(0,f.jsx)(_,{}),(0,f.jsx)(E,{}),(0,f.jsx)(S.A,{tag:x.Cy,locale:e}),(0,f.jsx)(h.A,{children:t.map(((e,t)=>(0,f.jsx)("meta",{...e},t)))})]})}const T=new Map;function A(e){if(T.has(e.pathname))return{...e,pathname:T.get(e.pathname)};if((0,d.u)(u.A,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return T.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return T.set(e.pathname,t),{...e,pathname:t}}var L=n(6125),P=n(6988),N=n(205);function j(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const O=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,N.A)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),j("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function I(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.u)(u.A,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class R extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.A.canUseDOM?j("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=j("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),I(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,f.jsx)(O,{previousLocation:this.previousLocation,location:t,children:(0,f.jsx)(c.qh,{location:t,render:()=>e})})}}const F=R,D="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner",z="__docusaurus-base-url-issue-banner-suggestion-container";function B(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${D}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var K=n(6921);const Z=new Set,X=new Set,J=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,ee={prefetch(e){if(!(e=>!J()&&!X.has(e)&&!Z.has(e))(e))return!1;Z.add(e);const t=(0,d.u)(u.A,e).flatMap((e=>{return t=e.route.path,Object.entries(G).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,K.A)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Y(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!J()&&!X.has(e))(e)&&(X.add(e),I(e))},te=Object.freeze(ee),ne=Boolean(!0);if(s.A.canUseDOM){window.docusaurus=te;const e=document.getElementById("__docusaurus"),t=(0,f.jsx)(i.vd,{children:(0,f.jsx)(o.Kd,{children:(0,f.jsx)(q,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},s=()=>{if(ne)r.startTransition((()=>{a.hydrateRoot(e,t,{onRecoverableError:n})}));else{const o=a.createRoot(e,{onRecoverableError:n});r.startTransition((()=>{o.render(t)}))}};I(window.location.pathname).then(s)}},6988:(e,t,n)=>{"use strict";n.d(t,{o:()=>d,l:()=>f});var r=n(6540),a=n(4784);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs","mainDocId":"intro","docs":[{"id":"APIs/Fmath","path":"/docs/APIs/Fmath","sidebar":"tutorialSidebar"},{"id":"APIs/PewPew","path":"/docs/APIs/PewPew","sidebar":"tutorialSidebar"},{"id":"APIs/standard-libraries","path":"/docs/APIs/standard-libraries","sidebar":"tutorialSidebar"},{"id":"APIs/types","path":"/docs/APIs/types","sidebar":"tutorialSidebar"},{"id":"File Information/manifest-files","path":"/docs/File Information/manifest-files","sidebar":"tutorialSidebar"},{"id":"File Information/mesh-files","path":"/docs/File Information/mesh-files","sidebar":"tutorialSidebar"},{"id":"File Information/sound-files","path":"/docs/File Information/sound-files","sidebar":"tutorialSidebar"},{"id":"Guides/Lua/advanced","path":"/docs/Guides/Lua/advanced","sidebar":"tutorialSidebar"},{"id":"Guides/Lua/beginner","path":"/docs/Guides/Lua/beginner","sidebar":"tutorialSidebar"},{"id":"Guides/Lua/intermediate","path":"/docs/Guides/Lua/intermediate","sidebar":"tutorialSidebar"},{"id":"Guides/Other/fps-animation","path":"/docs/Guides/Other/fps-animation","sidebar":"tutorialSidebar"},{"id":"intro","path":"/docs/intro","sidebar":"tutorialSidebar"},{"id":"other/level-design-principles","path":"/docs/other/level-design-principles","sidebar":"tutorialSidebar"},{"id":"other/level-restrictions","path":"/docs/other/level-restrictions","sidebar":"tutorialSidebar"},{"id":"other/trivia","path":"/docs/other/trivia","sidebar":"tutorialSidebar"}],"draftIds":[],"sidebars":{"tutorialSidebar":{"link":{"path":"/docs/intro","label":"intro"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var s=n(2654);const l=JSON.parse('{"docusaurusVersion":"3.1.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.1.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.1.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.1.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.1.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.1.1"},"@easyops-cn/docusaurus-search-local":{"type":"package","name":"@easyops-cn/docusaurus-search-local","version":"0.40.1"}}}');var u=n(4848);const c={siteConfig:a.default,siteMetadata:l,globalData:o,i18n:i,codeTranslations:s},d=r.createContext(c);function f(e){let{children:t}=e;return(0,u.jsx)(d.Provider,{value:c,children:t})}},7489:(e,t,n)=>{"use strict";n.d(t,{A:()=>p});var r=n(6540),a=n(8193),o=n(5260),i=n(440),s=n(5476),l=n(4848);function u(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,l.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,l.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,l.jsx)(c,{error:t})]})}function c(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,l.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function d(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)(p,{fallback:()=>(0,l.jsx)(u,{error:t,tryAgain:n}),children:[(0,l.jsx)(o.A,{children:(0,l.jsx)("title",{children:"Page Error"})}),(0,l.jsx)(s.A,{children:(0,l.jsx)(u,{error:t,tryAgain:n})})]})}const f=e=>(0,l.jsx)(d,{...e});class p extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.A.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??f)(e)}return e??null}}},8193:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5260:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});n(6540);var r=n(545),a=n(4848);function o(e){return(0,a.jsx)(r.mg,{...e})}},8774:(e,t,n)=>{"use strict";n.d(t,{A:()=>p});var r=n(6540),a=n(4625),o=n(440),i=n(4586),s=n(6654),l=n(8193),u=n(3427),c=n(6025),d=n(4848);function f(e,t){let{isNavLink:n,to:f,href:p,activeClassName:h,isActive:g,"data-noBrokenLinkCheck":m,autoAddBaseUrl:y=!0,...b}=e;const{siteConfig:{trailingSlash:v,baseUrl:w}}=(0,i.A)(),{withBaseUrl:x}=(0,c.h)(),k=(0,u.A)(),S=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>S.current));const E=f||p;const _=(0,s.A)(E),C=E?.replace("pathname://","");let T=void 0!==C?(A=C,y&&(e=>e.startsWith("/"))(A)?x(A):A):void 0;var A;T&&_&&(T=(0,o.applyTrailingSlash)(T,{trailingSlash:v,baseUrl:w}));const L=(0,r.useRef)(!1),P=n?a.k2:a.N_,N=l.A.canUseIntersectionObserver,j=(0,r.useRef)(),O=()=>{L.current||null==T||(window.docusaurus.preload(T),L.current=!0)};(0,r.useEffect)((()=>(!N&&_&&null!=T&&window.docusaurus.prefetch(T),()=>{N&&j.current&&j.current.disconnect()})),[j,T,N,_]);const I=T?.startsWith("#")??!1,R=!b.target||"_self"===b.target,F=!T||!_||!R||I;return m||!I&&F||k.collectLink(T),b.id&&k.collectAnchor(b.id),F?(0,d.jsx)("a",{ref:S,href:T,...E&&!_&&{target:"_blank",rel:"noopener noreferrer"},...b}):(0,d.jsx)(P,{...b,onMouseEnter:O,onTouchStart:O,innerRef:e=>{S.current=e,N&&e&&_&&(j.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(j.current.unobserve(e),j.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),j.current.observe(e))},to:T,...n&&{isActive:g,activeClassName:h}})}const p=r.forwardRef(f)},1312:(e,t,n)=>{"use strict";n.d(t,{A:()=>u,T:()=>l});var r=n(6540),a=n(4848);function o(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(2654);function s(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return o(s({message:n,id:r}),t)}function u(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const i=s({message:t,id:n});return(0,a.jsx)(a.Fragment,{children:o(i,r)})}},7065:(e,t,n)=>{"use strict";n.d(t,{W:()=>r});const r="default"},6654:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{A:()=>a,z:()=>r})},6025:(e,t,n)=>{"use strict";n.d(t,{A:()=>s,h:()=>i});var r=n(6540),a=n(4586),o=n(6654);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.A)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.z)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const s=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+s:s}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},3427:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});var r=n(6540);n(4848);const a=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),o=()=>(0,r.useContext)(a);function i(){return o()}},4586:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(6988);function o(){return(0,r.useContext)(a.o)}},2303:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});var r=n(6540),a=n(6125);function o(){return(0,r.useContext)(a.o)}},205:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});var r=n(6540);const a=n(8193).A.canUseDOM?r.useLayoutEffect:r.useEffect},6921:(e,t,n)=>{"use strict";n.d(t,{A:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const s=a?`${a}.${o}`:o;r(i)?e(i,s):t[s]=i}))}(e),t}},3102:(e,t,n)=>{"use strict";n.d(t,{W:()=>i,o:()=>o});var r=n(6540),a=n(4848);const o=r.createContext(null);function i(e){let{children:t,value:n}=e;const i=r.useContext(o),s=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:i,value:n})),[i,n]);return(0,a.jsx)(o.Provider,{value:s,children:t})}},4070:(e,t,n)=>{"use strict";n.d(t,{zK:()=>g,vT:()=>f,Gy:()=>c,HW:()=>m,ht:()=>d,r7:()=>h,jh:()=>p});var r=n(6347),a=n(4586),o=n(7065);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.A)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const s=e=>e.versions.find((e=>e.isLast));function l(e,t){const n=function(e,t){const n=s(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.B6)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),a=n?.docs.find((e=>!!(0,r.B6)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const u={},c=()=>i("docusaurus-plugin-content-docs")??u,d=e=>function(e,t,n){void 0===t&&(t=o.W),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function f(e){void 0===e&&(e={});const t=c(),{pathname:n}=(0,r.zy)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.B6)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function p(e){return d(e).versions}function h(e){const t=d(e);return s(t)}function g(e){const t=d(e),{pathname:n}=(0,r.zy)();return l(t,n)}function m(e){const t=d(e),{pathname:n}=(0,r.zy)();return function(e,t){const n=s(e);return{latestDocSuggestion:l(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},6294:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(5947),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},6134:(e,t,n)=>{"use strict";n.r(t);var r=n(1765),a=n(4784);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(9700),n(2719)(`./prism-${e}`)})),delete globalThis.Prism}(r.My)},1107:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});n(6540);var r=n(4164),a=n(1312),o=n(6342),i=n(8774),s=n(3427);const l={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var u=n(4848);function c(e){let{as:t,id:n,...c}=e;const d=(0,s.A)(),{navbar:{hideOnScroll:f}}=(0,o.p)();if("h1"===t||!n)return(0,u.jsx)(t,{...c,id:void 0});d.collectAnchor(n);const p=(0,a.T)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof c.children?c.children:n});return(0,u.jsxs)(t,{...c,className:(0,r.A)("anchor",f?l.anchorWithHideOnScrollNavbar:l.anchorWithStickyNavbar,c.className),id:n,children:[c.children,(0,u.jsx)(i.A,{className:"hash-link",to:`#${n}`,"aria-label":p,title:p,children:"\u200b"})]})}},3186:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});n(6540);const r={iconExternalLink:"iconExternalLink_nPIU"};var a=n(4848);function o(e){let{width:t=13.5,height:n=13.5}=e;return(0,a.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,a.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},5476:(e,t,n)=>{"use strict";n.d(t,{A:()=>Rt});var r=n(6540),a=n(4164),o=n(7489),i=n(1003),s=n(6347),l=n(1312),u=n(5062),c=n(4848);const d="__docusaurus_skipToContent_fallback";function f(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function p(){const e=(0,r.useRef)(null),{action:t}=(0,s.W6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&f(t)}),[]);return(0,u.$)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&f(e.current)})),{containerRef:e,onClick:n}}const h=(0,l.T)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function g(e){const t=e.children??h,{containerRef:n,onClick:r}=p();return(0,c.jsx)("div",{ref:n,role:"region","aria-label":h,children:(0,c.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var m=n(7559),y=n(4090);const b={skipToContent:"skipToContent_fXgn"};function v(){return(0,c.jsx)(g,{className:b.skipToContent})}var w=n(6342),x=n(5041);function k(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:a=1.2,className:o,...i}=e;return(0,c.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,c.jsx)("g",{stroke:r,strokeWidth:a,children:(0,c.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const S={closeButton:"closeButton_CVFx"};function E(e){return(0,c.jsx)("button",{type:"button","aria-label":(0,l.T)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,a.A)("clean-btn close",S.closeButton,e.className),children:(0,c.jsx)(k,{width:14,height:14,strokeWidth:3.1})})}const _={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.p)(),{content:n}=t;return(0,c.jsx)("div",{...e,className:(0,a.A)(_.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function A(){const{announcementBar:e}=(0,w.p)(),{isActive:t,close:n}=(0,x.Mj)();if(!t)return null;const{backgroundColor:r,textColor:a,isCloseable:o}=e;return(0,c.jsxs)("div",{className:T.announcementBar,style:{backgroundColor:r,color:a},role:"banner",children:[o&&(0,c.jsx)("div",{className:T.announcementBarPlaceholder}),(0,c.jsx)(C,{className:T.announcementBarContent}),o&&(0,c.jsx)(E,{onClick:n,className:T.announcementBarClose})]})}var L=n(9876),P=n(3104);var N=n(9532),j=n(5600);const O=r.createContext(null);function I(e){let{children:t}=e;const n=function(){const e=(0,L.M)(),t=(0,j.YL)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,N.ZC)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return(0,c.jsx)(O.Provider,{value:n,children:t})}function R(e){if(e.component){const t=e.component;return(0,c.jsx)(t,{...e.props})}}function F(){const e=(0,r.useContext)(O);if(!e)throw new N.dV("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,j.YL)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:R(o)})),[a,o,t])}function D(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:o}=F();return(0,c.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,c.jsxs)("div",{className:(0,a.A)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":o}),children:[(0,c.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,c.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var M=n(5293),z=n(2303);function B(e){return(0,c.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,c.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function $(e){return(0,c.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,c.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function Q(e){let{className:t,buttonClassName:n,value:r,onChange:o}=e;const i=(0,z.A)(),s=(0,l.T)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,l.T)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,l.T)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,c.jsx)("div",{className:(0,a.A)(U.toggle,t),children:(0,c.jsxs)("button",{className:(0,a.A)("clean-btn",U.toggleButton,!i&&U.toggleButtonDisabled,n),type:"button",onClick:()=>o("dark"===r?"light":"dark"),disabled:!i,title:s,"aria-label":s,"aria-live":"polite",children:[(0,c.jsx)(B,{className:(0,a.A)(U.toggleIcon,U.lightToggleIcon)}),(0,c.jsx)($,{className:(0,a.A)(U.toggleIcon,U.darkToggleIcon)})]})})}const V=r.memo(Q),H={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function W(e){let{className:t}=e;const n=(0,w.p)().navbar.style,r=(0,w.p)().colorMode.disableSwitch,{colorMode:a,setColorMode:o}=(0,M.G)();return r?null:(0,c.jsx)(V,{className:t,buttonClassName:"dark"===n?H.darkNavbarColorModeToggle:void 0,value:a,onChange:o})}var q=n(3465);function G(){return(0,c.jsx)(q.A,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function Y(){const e=(0,L.M)();return(0,c.jsx)("button",{type:"button","aria-label":(0,l.T)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,c.jsx)(k,{color:"var(--ifm-color-emphasis-600)"})})}function K(){return(0,c.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,c.jsx)(G,{}),(0,c.jsx)(W,{className:"margin-right--md"}),(0,c.jsx)(Y,{})]})}var Z=n(8774),X=n(6025),J=n(6654);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(3186);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:a,label:o,html:i,isDropdownLink:s,prependBaseUrlToHref:l,...u}=e;const d=(0,X.A)(r),f=(0,X.A)(t),p=(0,X.A)(a,{forcePrependBaseUrl:!0}),h=o&&a&&!(0,J.A)(a),g=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,c.jsxs)(c.Fragment,{children:[o,h&&(0,c.jsx)(te.A,{...s&&{width:12,height:12}})]})};return a?(0,c.jsx)(Z.A,{href:l?p:a,...u,...g}):(0,c.jsx)(Z.A,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(f)},...u,...g})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const o=(0,c.jsx)(ne,{className:(0,a.A)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,c.jsx)("li",{children:o}):o}function ae(e){let{className:t,isDropdownItem:n,...r}=e;return(0,c.jsx)("li",{className:"menu__list-item",children:(0,c.jsx)(ne,{className:(0,a.A)("menu__link",t),...r})})}function oe(e){let{mobile:t=!1,position:n,...r}=e;const a=t?ae:re;return(0,c.jsx)(a,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ie=n(1422),se=n(9169),le=n(4586);const ue={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function ce(e,t){return e.some((e=>function(e,t){return!!(0,se.ys)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function de(e){let{items:t,position:n,className:o,onClick:i,...s}=e;const l=(0,r.useRef)(null),[u,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{l.current&&!l.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[l]),(0,c.jsxs)("div",{ref:l,className:(0,a.A)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":u}),children:[(0,c.jsx)(ne,{"aria-haspopup":"true","aria-expanded":u,role:"button",href:s.to?void 0:"#",className:(0,a.A)("navbar__link",o),...s,onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!u))},children:s.children??s.label}),(0,c.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(qe,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function fe(e){let{items:t,className:n,position:o,onClick:i,...l}=e;const u=function(){const{siteConfig:{baseUrl:e}}=(0,le.A)(),{pathname:t}=(0,s.zy)();return t.replace(e,"/")}(),d=ce(t,u),{collapsed:f,toggleCollapsed:p,setCollapsed:h}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&h(!d)}),[u,d,h]),(0,c.jsxs)("li",{className:(0,a.A)("menu__list-item",{"menu__list-item--collapsed":f}),children:[(0,c.jsx)(ne,{role:"button",className:(0,a.A)(ue.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...l,onClick:e=>{e.preventDefault(),p()},children:l.children??l.label}),(0,c.jsx)(ie.N,{lazy:!0,as:"ul",className:"menu__list",collapsed:f,children:t.map(((e,t)=>(0,r.createElement)(qe,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function pe(e){let{mobile:t=!1,...n}=e;const r=t?fe:de;return(0,c.jsx)(r,{...n})}var he=n(2131);function ge(e){let{width:t=20,height:n=20,...r}=e;return(0,c.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,c.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const me="iconLanguage_nlXk";var ye=n(1088),be=n(5391),ve=n(5597),we=n(4070),xe=n(5891),ke=n(2384),Se=n(4471),Ee=n(7674),_e=n(6841),Ce=n(3810);const Te='',Ae='',Le='',Pe='',Ne='',je='',Oe='',Ie={searchBar:"searchBar_RVTs",dropdownMenu:"dropdownMenu_qbY6",searchBarLeft:"searchBarLeft_MXDe",suggestion:"suggestion_fB_2",cursor:"cursor_eG29",hitTree:"hitTree_kk6K",hitIcon:"hitIcon_a7Zy",hitPath:"hitPath_ieM4",noResultsIcon:"noResultsIcon_EBY5",hitFooter:"hitFooter_E9YW",hitWrapper:"hitWrapper_sAK8",hitTitle:"hitTitle_vyVt",hitAction:"hitAction_NqkB",hideAction:"hideAction_vcyE",noResults:"noResults_l6Q3",searchBarContainer:"searchBarContainer_NW3z",searchBarLoadingRing:"searchBarLoadingRing_YnHq",searchClearButton:"searchClearButton_qk4g",searchIndexLoading:"searchIndexLoading_EJ1f",searchHintContainer:"searchHintContainer_Pkmr",searchHint:"searchHint_iIMx",focused:"focused_OWtg",input:"input_FOTf",hint:"hint_URu1",suggestions:"suggestions_X8XU",dataset:"dataset_QiCy",empty:"empty_eITn"};function Re(e){let{document:t,type:n,page:r,metadata:a,tokens:o,isInterOfTree:i,isLastOfTree:s}=e;const l=0===n,u=1===n,c=[];i?c.push(je):s&&c.push(Oe);const d=c.map((e=>`${e}`)),f=`${l?Te:u?Ae:Le}`,p=[`${(0,Ce.C)(t.t,(0,Ee.g)(a,"t"),o)}`];if(!i&&!s&&ye.tb){const e=r?(r.b??[]).concat(r.t).concat(t.s&&t.s!==r.t?t.s:[]):t.b;p.push(`${(0,Se.$)(e??[])}`)}else l||p.push(`${(0,_e.Z)(r.t||(t.u.startsWith("/docs/api-reference/")?"API Reference":""),o)}`);const h=`${Pe}`;return[...d,f,``,...p,"",h].join("")}function Fe(){return`${Ne}${(0,l.T)({id:"theme.SearchBar.noResultsText",message:"No results"})}`}var De=n(2849),Me=n(3385);async function ze(){const e=await Promise.all([n.e(489),n.e(5741)]).then(n.t.bind(n,489,23)),t=e.default;return t.noConflict?t.noConflict():e.noConflict&&e.noConflict(),t}const Be="_highlight";const $e=function(e){let{handleSearchBarToggle:t}=e;const n=(0,z.A)(),{siteConfig:{baseUrl:a},i18n:{currentLocale:o}}=(0,le.A)(),i=(0,we.vT)();let u=a;try{const{preferredVersion:e}=(0,ve.g1)(i?.pluginId??ye.UB);e&&!e.isLast&&(u=e.path+"/")}catch(D){if(ye.I$&&!(D instanceof N.dV))throw D}const d=(0,s.W6)(),f=(0,s.zy)(),p=(0,r.useRef)(null),h=(0,r.useRef)(new Map),g=(0,r.useRef)(!1),[m,y]=(0,r.useState)(!1),[b,v]=(0,r.useState)(!1),[w,x]=(0,r.useState)(""),k=(0,r.useRef)(null),S=(0,r.useRef)(""),[E,_]=(0,r.useState)("");(0,r.useEffect)((()=>{if(!Array.isArray(ye.Hg))return;let e="";if(f.pathname.startsWith(u)){const t=f.pathname.substring(u.length);let n;for(const e of ye.Hg){const r="string"==typeof e?e:e.path;if(t===r||t.startsWith(`${r}/`)){n=r;break}}n&&(e=n)}S.current!==e&&(h.current.delete(e),S.current=e),_(e)}),[f.pathname,u]);const C=!!ye.O6&&Array.isArray(ye.Hg)&&""===E,T=(0,r.useCallback)((async()=>{if(C||h.current.get(E))return;h.current.set(E,"loading"),k.current?.autocomplete.destroy(),y(!0);const[{wrappedIndexes:e,zhDictionary:t},n]=await Promise.all([(0,xe.Z)(u,E),ze()]);if(k.current=n(p.current,{hint:!1,autoselect:!0,openOnFocus:!0,cssClasses:{root:(0,be.A)(Ie.searchBar,{[Ie.searchBarLeft]:"left"===ye.ZG}),noPrefix:!0,dropdownMenu:Ie.dropdownMenu,input:Ie.input,hint:Ie.hint,suggestions:Ie.suggestions,suggestion:Ie.suggestion,cursor:Ie.cursor,dataset:Ie.dataset,empty:Ie.empty}},[{source:(0,ke.m)(e,t,ye.AT),templates:{suggestion:Re,empty:Fe,footer:e=>{let{query:t,isEmpty:n}=e;if(n&&(!E||!ye.dz))return;const r=(e=>{let{query:t,isEmpty:n}=e;const r=document.createElement("a"),i=new URLSearchParams;let s;if(i.set("q",t),E){const e=E&&Array.isArray(ye.Hg)?ye.Hg.find((e=>"string"==typeof e?e===E:e.path===E)):E,t=e?(0,Me.p)(e,o).label:E;s=ye.dz&&n?(0,l.T)({id:"theme.SearchBar.seeAllOutsideContext",message:"See results outside {context}"},{context:t}):(0,l.T)({id:"theme.SearchBar.searchInContext",message:"See all results in {context}"},{context:t})}else s=(0,l.T)({id:"theme.SearchBar.seeAll",message:"See all results"});if(!E||!Array.isArray(ye.Hg)||ye.dz&&n||i.set("ctx",E),u!==a){if(!u.startsWith(a))throw new Error(`Version url '${u}' does not start with base url '${a}', this is a bug of \`@easyops-cn/docusaurus-search-local\`, please report it.`);i.set("version",u.substring(a.length))}const c=`${a}search?${i.toString()}`;return r.href=c,r.textContent=s,r.addEventListener("click",(e=>{e.ctrlKey||e.metaKey||(e.preventDefault(),k.current?.autocomplete.close(),d.push(c))})),r})({query:t,isEmpty:n}),i=document.createElement("div");return i.className=Ie.hitFooter,i.appendChild(r),i}}}]).on("autocomplete:selected",(function(e,t){let{document:{u:n,h:r},tokens:a}=t;p.current?.blur();let o=n;if(ye.CU&&a.length>0){const e=new URLSearchParams;for(const t of a)e.append(Be,t);o+=`?${e.toString()}`}r&&(o+=r),d.push(o)})).on("autocomplete:closed",(()=>{p.current?.blur()})),h.current.set(E,"done"),y(!1),g.current){const e=p.current;e.value&&k.current?.autocomplete.open(),e.focus()}}),[C,E,u,a,d]);(0,r.useEffect)((()=>{if(!ye.CU)return;const e=n?new URLSearchParams(f.search).getAll(Be):[];setTimeout((()=>{const t=document.querySelector("article");if(!t)return;const n=new ye.CU(t);n.unmark(),0!==e.length&&n.mark(e),x(e.join(" ")),k.current?.autocomplete.setVal(e.join(" "))}))}),[n,f.search,f.pathname]);const[A,L]=(0,r.useState)(!1),P=(0,r.useCallback)((()=>{g.current=!0,T(),L(!0),t?.(!0)}),[t,T]),j=(0,r.useCallback)((()=>{L(!1),t?.(!1)}),[t]),O=(0,r.useCallback)((()=>{T()}),[T]),I=(0,r.useCallback)((e=>{x(e.target.value),e.target.value&&v(!0)}),[]),R=!!n&&/mac/i.test(navigator.userAgentData?.platform??navigator.platform);(0,r.useEffect)((()=>{if(!ye.WW)return;const e=e=>{!(R?e.metaKey:e.ctrlKey)||"k"!==e.key&&"K"!==e.key||(e.preventDefault(),p.current?.focus(),P())};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}}),[R,P]);const F=(0,r.useCallback)((()=>{const e=new URLSearchParams(f.search);e.delete(Be);const t=e.toString(),n=f.pathname+(""!=t?`?${t}`:"")+f.hash;n!=f.pathname+f.search+f.hash&&d.push(n),x(""),k.current?.autocomplete.setVal("")}),[f.pathname,f.search,f.hash,d]);return(0,c.jsxs)("div",{className:(0,be.A)("navbar__search",Ie.searchBarContainer,{[Ie.searchIndexLoading]:m&&b,[Ie.focused]:A}),hidden:C,children:[(0,c.jsx)("input",{placeholder:(0,l.T)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),"aria-label":"Search",className:"navbar__search-input",onMouseEnter:O,onFocus:P,onBlur:j,onChange:I,ref:p,value:w}),(0,c.jsx)(De.A,{className:Ie.searchBarLoadingRing}),ye.WW&&ye.pk&&(""!==w?(0,c.jsx)("button",{className:Ie.searchClearButton,onClick:F,children:"\u2715"}):n&&(0,c.jsxs)("div",{className:Ie.searchHintContainer,children:[(0,c.jsx)("kbd",{className:Ie.searchHint,children:R?"\u2318":"ctrl"}),(0,c.jsx)("kbd",{className:Ie.searchHint,children:"K"})]}))]})},Ue={navbarSearchContainer:"navbarSearchContainer_Bca1"};function Qe(e){let{children:t,className:n}=e;return(0,c.jsx)("div",{className:(0,a.A)(n,Ue.navbarSearchContainer),children:t})}var Ve=n(1754);const He=e=>e.docs.find((t=>t.id===e.mainDocId));const We={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:a="",...o}=e;const{i18n:{currentLocale:i,locales:u,localeConfigs:d}}=(0,le.A)(),f=(0,he.o)(),{search:p,hash:h}=(0,s.zy)(),g=[...n,...u.map((e=>{const n=`${`pathname://${f.createUrl({locale:e,fullyQualified:!1})}`}${p}${h}${a}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...r],m=t?(0,l.T)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return(0,c.jsx)(pe,{...o,mobile:t,label:(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(ge,{className:me}),m]}),items:g})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,c.jsx)(Qe,{className:n,children:(0,c.jsx)($e,{})})},dropdown:pe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:o=!1}=e;const i=o?"li":"div";return(0,c.jsx)(i,{className:(0,a.A)({navbar__item:!r&&!o,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...a}=e;const{activeDoc:o}=(0,we.zK)(r),i=(0,Ve.QB)(t,r),s=o?.path===i?.path;return null===i||i.unlisted&&!s?null:(0,c.jsx)(oe,{exact:!0,...a,isActive:()=>s||!!o?.sidebar&&o.sidebar===i.sidebar,label:n??i.id,to:i.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...a}=e;const{activeDoc:o}=(0,we.zK)(r),i=(0,Ve.fW)(t,r).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,c.jsx)(oe,{exact:!0,...a,isActive:()=>o?.sidebar===t,label:n??i.label,to:i.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...a}=e;const o=(0,Ve.Vd)(r)[0],i=t??o.label,s=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(o).path;return(0,c.jsx)(oe,{...a,label:i,to:s})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:a,dropdownItemsAfter:o,...i}=e;const{search:u,hash:d}=(0,s.zy)(),f=(0,we.zK)(n),p=(0,we.jh)(n),{savePreferredVersionName:h}=(0,ve.g1)(n),g=[...a,...p.map((e=>{const t=f.alternateDocVersions[e.name]??He(e);return{label:e.label,to:`${t.path}${u}${d}`,isActive:()=>e===f.activeVersion,onClick:()=>h(e.name)}})),...o],m=(0,Ve.Vd)(n)[0],y=t&&g.length>1?(0,l.T)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):m.label,b=t&&g.length>1?void 0:He(m).path;return g.length<=1?(0,c.jsx)(oe,{...i,mobile:t,label:y,to:b,isActive:r?()=>!1:void 0}):(0,c.jsx)(pe,{...i,mobile:t,label:y,to:b,items:g,isActive:r?()=>!1:void 0})}};function qe(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),a=We[r];if(!a)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,c.jsx)(a,{...n})}function Ge(){const e=(0,L.M)(),t=(0,w.p)().navbar.items;return(0,c.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(qe,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ye(e){return(0,c.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,c.jsx)(l.A,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Ke(){const e=0===(0,w.p)().navbar.items.length,t=F();return(0,c.jsxs)(c.Fragment,{children:[!e&&(0,c.jsx)(Ye,{onClick:()=>t.hide()}),t.content]})}function Ze(){const e=(0,L.M)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,c.jsx)(D,{header:(0,c.jsx)(K,{}),primaryMenu:(0,c.jsx)(Ge,{}),secondaryMenu:(0,c.jsx)(Ke,{})}):null}const Xe={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Je(e){return(0,c.jsx)("div",{role:"presentation",...e,className:(0,a.A)("navbar-sidebar__backdrop",e.className)})}function et(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,w.p)(),i=(0,L.M)(),{navbarRef:s,isNavbarVisible:d}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,P.Mq)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=s?n(!1):i+u{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,c.jsxs)("nav",{ref:s,"aria-label":(0,l.T)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.A)("navbar","navbar--fixed-top",n&&[Xe.navbarHideable,!d&&Xe.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown}),children:[t,(0,c.jsx)(Je,{onClick:i.toggle}),(0,c.jsx)(Ze,{})]})}var tt=n(440);const nt={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};function rt(e){return(0,c.jsx)("button",{type:"button",...e,children:(0,c.jsx)(l.A,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function at(e){let{error:t}=e;const n=(0,tt.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,c.jsx)("p",{className:nt.errorBoundaryError,children:n})}class ot extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const it="right";function st(e){let{width:t=30,height:n=30,className:r,...a}=e;return(0,c.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...a,children:(0,c.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function lt(){const{toggle:e,shown:t}=(0,L.M)();return(0,c.jsx)("button",{onClick:e,"aria-label":(0,l.T)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,c.jsx)(st,{})})}const ut={colorModeToggle:"colorModeToggle_DEke"};function ct(e){let{items:t}=e;return(0,c.jsx)(c.Fragment,{children:t.map(((e,t)=>(0,c.jsx)(ot,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,c.jsx)(qe,{...e})},t)))})}function dt(e){let{left:t,right:n}=e;return(0,c.jsxs)("div",{className:"navbar__inner",children:[(0,c.jsx)("div",{className:"navbar__items",children:t}),(0,c.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function ft(){const e=(0,L.M)(),t=(0,w.p)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??it)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),a=t.find((e=>"search"===e.type));return(0,c.jsx)(dt,{left:(0,c.jsxs)(c.Fragment,{children:[!e.disabled&&(0,c.jsx)(lt,{}),(0,c.jsx)(G,{}),(0,c.jsx)(ct,{items:n})]}),right:(0,c.jsxs)(c.Fragment,{children:[(0,c.jsx)(ct,{items:r}),(0,c.jsx)(W,{className:ut.colorModeToggle}),!a&&(0,c.jsx)(Qe,{children:(0,c.jsx)($e,{})})]})})}function pt(){return(0,c.jsx)(et,{children:(0,c.jsx)(ft,{})})}function ht(e){let{item:t}=e;const{to:n,href:r,label:a,prependBaseUrlToHref:o,...i}=t,s=(0,X.A)(n),l=(0,X.A)(r,{forcePrependBaseUrl:!0});return(0,c.jsxs)(Z.A,{className:"footer__link-item",...r?{href:o?l:r}:{to:s},...i,children:[a,r&&!(0,J.A)(r)&&(0,c.jsx)(te.A,{})]})}function gt(e){let{item:t}=e;return t.html?(0,c.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,c.jsx)("li",{className:"footer__item",children:(0,c.jsx)(ht,{item:t})},t.href??t.to)}function mt(e){let{column:t}=e;return(0,c.jsxs)("div",{className:"col footer__col",children:[(0,c.jsx)("div",{className:"footer__title",children:t.title}),(0,c.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,c.jsx)(gt,{item:e},t)))})]})}function yt(e){let{columns:t}=e;return(0,c.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,c.jsx)(mt,{column:e},t)))})}function bt(){return(0,c.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function vt(e){let{item:t}=e;return t.html?(0,c.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,c.jsx)(ht,{item:t})}function wt(e){let{links:t}=e;return(0,c.jsx)("div",{className:"footer__links text--center",children:(0,c.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,c.jsxs)(r.Fragment,{children:[(0,c.jsx)(vt,{item:e}),t.length!==n+1&&(0,c.jsx)(bt,{})]},n)))})})}function xt(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,c.jsx)(yt,{columns:t}):(0,c.jsx)(wt,{links:t})}var kt=n(1122);const St={footerLogoLink:"footerLogoLink_BH7S"};function Et(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.h)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,c.jsx)(kt.A,{className:(0,a.A)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function _t(e){let{logo:t}=e;return t.href?(0,c.jsx)(Z.A,{href:t.href,className:St.footerLogoLink,target:t.target,children:(0,c.jsx)(Et,{logo:t})}):(0,c.jsx)(Et,{logo:t})}function Ct(e){let{copyright:t}=e;return(0,c.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function Tt(e){let{style:t,links:n,logo:r,copyright:o}=e;return(0,c.jsx)("footer",{className:(0,a.A)("footer",{"footer--dark":"dark"===t}),children:(0,c.jsxs)("div",{className:"container container-fluid",children:[n,(r||o)&&(0,c.jsxs)("div",{className:"footer__bottom text--center",children:[r&&(0,c.jsx)("div",{className:"margin-bottom--sm",children:r}),o]})]})})}function At(){const{footer:e}=(0,w.p)();if(!e)return null;const{copyright:t,links:n,logo:r,style:a}=e;return(0,c.jsx)(Tt,{style:a,links:n&&n.length>0&&(0,c.jsx)(xt,{links:n}),logo:r&&(0,c.jsx)(_t,{logo:r}),copyright:t&&(0,c.jsx)(Ct,{copyright:t})})}const Lt=r.memo(At),Pt=(0,N.fM)([M.a,x.oq,P.Tv,ve.VQ,i.Jx,function(e){let{children:t}=e;return(0,c.jsx)(j.y_,{children:(0,c.jsx)(L.e,{children:(0,c.jsx)(I,{children:t})})})}]);function Nt(e){let{children:t}=e;return(0,c.jsx)(Pt,{children:t})}var jt=n(1107);function Ot(e){let{error:t,tryAgain:n}=e;return(0,c.jsx)("main",{className:"container margin-vert--xl",children:(0,c.jsx)("div",{className:"row",children:(0,c.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,c.jsx)(jt.A,{as:"h1",className:"hero__title",children:(0,c.jsx)(l.A,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,c.jsx)("div",{className:"margin-vert--lg",children:(0,c.jsx)(rt,{onClick:n,className:"button button--primary shadow--lw"})}),(0,c.jsx)("hr",{}),(0,c.jsx)("div",{className:"margin-vert--md",children:(0,c.jsx)(at,{error:t})})]})})})}const It={mainWrapper:"mainWrapper_z2l0"};function Rt(e){const{children:t,noFooter:n,wrapperClassName:r,title:s,description:l}=e;return(0,y.J)(),(0,c.jsxs)(Nt,{children:[(0,c.jsx)(i.be,{title:s,description:l}),(0,c.jsx)(v,{}),(0,c.jsx)(A,{}),(0,c.jsx)(pt,{}),(0,c.jsx)("div",{id:d,className:(0,a.A)(m.G.wrapper.main,It.mainWrapper,r),children:(0,c.jsx)(o.A,{fallback:e=>(0,c.jsx)(Ot,{...e}),children:t})}),!n&&(0,c.jsx)(Lt,{})]})}},3465:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});n(6540);var r=n(8774),a=n(6025),o=n(4586),i=n(6342),s=n(1122),l=n(4848);function u(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,a.A)(t.src),dark:(0,a.A)(t.srcDark||t.src)},i=(0,l.jsx)(s.A,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,l.jsx)("div",{className:r,children:i}):i}function c(e){const{siteConfig:{title:t}}=(0,o.A)(),{navbar:{title:n,logo:s}}=(0,i.p)(),{imageClassName:c,titleClassName:d,...f}=e,p=(0,a.A)(s?.href||"/"),h=n?"":t,g=s?.alt??h;return(0,l.jsxs)(r.A,{to:p,...f,...s?.target&&{target:s.target},children:[s&&(0,l.jsx)(u,{logo:s,alt:g,imageClassName:c}),null!=n&&(0,l.jsx)("b",{className:d,children:n})]})}},1463:(e,t,n)=>{"use strict";n.d(t,{A:()=>o});n(6540);var r=n(5260),a=n(4848);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return(0,a.jsxs)(r.A,{children:[t&&(0,a.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,a.jsx)("meta",{name:"docusaurus_version",content:n}),o&&(0,a.jsx)("meta",{name:"docusaurus_tag",content:o}),i&&(0,a.jsx)("meta",{name:"docsearch:language",content:i}),n&&(0,a.jsx)("meta",{name:"docsearch:version",content:n}),o&&(0,a.jsx)("meta",{name:"docsearch:docusaurus_tag",content:o})]})}},1122:(e,t,n)=>{"use strict";n.d(t,{A:()=>c});var r=n(6540),a=n(4164),o=n(2303),i=n(5293);const s={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var l=n(4848);function u(e){let{className:t,children:n}=e;const u=(0,o.A)(),{colorMode:c}=(0,i.G)();return(0,l.jsx)(l.Fragment,{children:(u?"dark"===c?["dark"]:["light"]:["light","dark"]).map((e=>{const o=n({theme:e,className:(0,a.A)(t,s.themedComponent,s[`themedComponent--${e}`])});return(0,l.jsx)(r.Fragment,{children:o},e)}))})}function c(e){const{sources:t,className:n,alt:r,...a}=e;return(0,l.jsx)(u,{className:n,children:e=>{let{theme:n,className:o}=e;return(0,l.jsx)("img",{src:t[n],alt:r,className:o,...a})}})}},1422:(e,t,n)=>{"use strict";n.d(t,{N:()=>y,u:()=>u});var r=n(6540),a=n(8193),o=n(205),i=n(3109),s=n(4848);const l="ease-in-out";function u(e){let{initialState:t}=e;const[n,a]=(0,r.useState)(t??!1),o=(0,r.useCallback)((()=>{a((e=>!e))}),[]);return{collapsed:n,setCollapsed:a,toggleCollapsed:o}}const c={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function f(e,t){const n=t?c:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function p(e){let{collapsibleRef:t,collapsed:n,animation:a}=e;const o=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=a?.duration??function(e){if((0,i.O)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${a?.easing??l}`,height:`${t}px`}}function s(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return f(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=c.height,e.style.overflow=c.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,a])}function h(e){if(!a.A.canUseDOM)return e?c:d}function g(e){let{as:t="div",collapsed:n,children:a,animation:o,onCollapseTransitionEnd:i,className:l,disableSSRStyle:u}=e;const c=(0,r.useRef)(null);return p({collapsibleRef:c,collapsed:n,animation:o}),(0,s.jsx)(t,{ref:c,style:u?void 0:h(n),onTransitionEnd:e=>{"height"===e.propertyName&&(f(c.current,n),i?.(n))},className:l,children:a})}function m(e){let{collapsed:t,...n}=e;const[a,i]=(0,r.useState)(!t),[l,u]=(0,r.useState)(t);return(0,o.A)((()=>{t||i(!0)}),[t]),(0,o.A)((()=>{a&&u(t)}),[a,t]),a?(0,s.jsx)(g,{...n,collapsed:l}):null}function y(e){let{lazy:t,...n}=e;const r=t?m:g;return(0,s.jsx)(r,{...n})}},5041:(e,t,n)=>{"use strict";n.d(t,{Mj:()=>g,oq:()=>h});var r=n(6540),a=n(2303),o=n(9466),i=n(9532),s=n(6342),l=n(4848);const u=(0,o.Wf)("docusaurus.announcement.dismiss"),c=(0,o.Wf)("docusaurus.announcement.id"),d=()=>"true"===u.get(),f=e=>u.set(String(e)),p=r.createContext(null);function h(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.p)(),t=(0,a.A)(),[n,o]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{o(d())}),[]);const i=(0,r.useCallback)((()=>{f(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=c.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;c.set(t),r&&f(!1),!r&&d()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,l.jsx)(p.Provider,{value:n,children:t})}function g(){const e=(0,r.useContext)(p);if(!e)throw new i.dV("AnnouncementBarProvider");return e}},5293:(e,t,n)=>{"use strict";n.d(t,{G:()=>y,a:()=>m});var r=n(6540),a=n(8193),o=n(9532),i=n(9466),s=n(6342),l=n(4848);const u=r.createContext(void 0),c="theme",d=(0,i.Wf)(c),f={light:"light",dark:"dark"},p=e=>e===f.dark?f.dark:f.light,h=e=>a.A.canUseDOM?p(document.documentElement.getAttribute("data-theme")):p(e),g=e=>{d.set(p(e))};function m(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.p)(),[a,o]=(0,r.useState)(h(e));(0,r.useEffect)((()=>{t&&d.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&g(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?f.dark:f.light:e),d.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",p(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==c)return;const t=d.get();null!==t&&i(p(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const l=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||l.current?l.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===f.dark},setLightTheme(){i(f.light)},setDarkTheme(){i(f.dark)}})),[a,i])}();return(0,l.jsx)(u.Provider,{value:n,children:t})}function y(){const e=(0,r.useContext)(u);if(null==e)throw new o.dV("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},5597:(e,t,n)=>{"use strict";n.d(t,{VQ:()=>y,g1:()=>v});var r=n(6540),a=n(4070),o=n(7065),i=n(6342),s=n(1754),l=n(9532),u=n(9466),c=n(4848);const d=e=>`docs-preferred-version-${e}`,f={save:(e,t,n)=>{(0,u.Wf)(d(e),{persistence:t}).set(n)},read:(e,t)=>(0,u.Wf)(d(e),{persistence:t}).get(),clear:(e,t)=>{(0,u.Wf)(d(e),{persistence:t}).del()}},p=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const h=r.createContext(null);function g(){const e=(0,a.Gy)(),t=(0,i.p)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,s]=(0,r.useState)((()=>p(n)));(0,r.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=f.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(f.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){f.save(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function m(e){let{children:t}=e;const n=g();return(0,c.jsx)(h.Provider,{value:n,children:t})}function y(e){let{children:t}=e;return s.C5?(0,c.jsx)(m,{children:t}):(0,c.jsx)(c.Fragment,{children:t})}function b(){const e=(0,r.useContext)(h);if(!e)throw new l.dV("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=o.W);const t=(0,a.ht)(e),[n,i]=b(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},6588:(e,t,n)=>{"use strict";n.d(t,{V:()=>l,t:()=>u});var r=n(6540),a=n(9532),o=n(4848);const i=Symbol("EmptyContext"),s=r.createContext(i);function l(e){let{children:t,name:n,items:a}=e;const i=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return(0,o.jsx)(s.Provider,{value:i,children:t})}function u(){const e=(0,r.useContext)(s);if(e===i)throw new a.dV("DocsSidebarProvider");return e}},2252:(e,t,n)=>{"use strict";n.d(t,{n:()=>s,r:()=>l});var r=n(6540),a=n(9532),o=n(4848);const i=r.createContext(null);function s(e){let{children:t,version:n}=e;return(0,o.jsx)(i.Provider,{value:n,children:t})}function l(){const e=(0,r.useContext)(i);if(null===e)throw new a.dV("DocsVersionProvider");return e}},9876:(e,t,n)=>{"use strict";n.d(t,{e:()=>p,M:()=>h});var r=n(6540),a=n(5600),o=n(4581),i=n(6347),s=n(9532);function l(e){!function(e){const t=(0,i.W6)(),n=(0,s._q)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var u=n(6342),c=n(4848);const d=r.createContext(void 0);function f(){const e=function(){const e=(0,a.YL)(),{items:t}=(0,u.p)().navbar;return 0===t.length&&!e.component}(),t=(0,o.l)(),n=!e&&"mobile"===t,[i,s]=(0,r.useState)(!1);l((()=>{if(i)return s(!1),!1}));const c=(0,r.useCallback)((()=>{s((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&s(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:c,shown:i})),[e,n,c,i])}function p(e){let{children:t}=e;const n=f();return(0,c.jsx)(d.Provider,{value:n,children:t})}function h(){const e=r.useContext(d);if(void 0===e)throw new s.dV("NavbarMobileSidebarProvider");return e}},5600:(e,t,n)=>{"use strict";n.d(t,{GX:()=>u,YL:()=>l,y_:()=>s});var r=n(6540),a=n(9532),o=n(4848);const i=r.createContext(null);function s(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,o.jsx)(i.Provider,{value:n,children:t})}function l(){const e=(0,r.useContext)(i);if(!e)throw new a.dV("NavbarSecondaryMenuContentProvider");return e[0]}function u(e){let{component:t,props:n}=e;const o=(0,r.useContext)(i);if(!o)throw new a.dV("NavbarSecondaryMenuContentProvider");const[,s]=o,l=(0,a.Be)(n);return(0,r.useEffect)((()=>{s({component:t,props:l})}),[s,t,l]),(0,r.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},4090:(e,t,n)=>{"use strict";n.d(t,{w:()=>a,J:()=>o});var r=n(6540);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},4581:(e,t,n)=>{"use strict";n.d(t,{l:()=>s});var r=n(6540),a=n(8193);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function s(e){let{desktopBreakpoint:t=i}=void 0===e?{}:e;const[n,s]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){s(function(e){if(!a.A.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?o.desktop:o.mobile}(t))}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[t]),n}},7559:(e,t,n)=>{"use strict";n.d(t,{G:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},3109:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{O:()=>r})},1754:(e,t,n)=>{"use strict";n.d(t,{Nr:()=>p,w8:()=>m,C5:()=>f,B5:()=>E,Vd:()=>x,QB:()=>S,fW:()=>k,OF:()=>w,Y:()=>b});var r=n(6540),a=n(6347),o=n(2831),i=n(4070),s=n(5597),l=n(2252),u=n(6588);function c(e){return Array.from(new Set(e))}var d=n(9169);const f=!!i.Gy;function p(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=p(t);if(e)return e}}(e):void 0:e.href}const h=(e,t)=>void 0!==e&&(0,d.ys)(e,t),g=(e,t)=>e.some((e=>m(e,t)));function m(e,t){return"link"===e.type?h(e.href,t):"category"===e.type&&(h(e.href,t)||g(e.items,t))}function y(e,t){switch(e.type){case"category":return m(e,t)||e.items.some((e=>y(e,t)));case"link":return!e.unlisted||m(e,t);default:return!0}}function b(e,t){return(0,r.useMemo)((()=>e.filter((e=>y(e,t)))),[e,t])}function v(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,d.ys)(o.href,n)||e(o.items))||"link"===o.type&&(0,d.ys)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function w(){const e=(0,u.t)(),{pathname:t}=(0,a.zy)(),n=(0,i.vT)()?.pluginData.breadcrumbs;return!1!==n&&e?v({sidebarItems:e.items,pathname:t}):null}function x(e){const{activeVersion:t}=(0,i.zK)(e),{preferredVersion:n}=(0,s.g1)(e),a=(0,i.r7)(e);return(0,r.useMemo)((()=>c([t,n,a].filter(Boolean))),[t,n,a])}function k(e,t){const n=x(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function S(e,t){const n=x(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${c(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function E(e){let{route:t}=e;const n=(0,a.zy)(),r=(0,l.r)(),i=t.routes,s=i.find((e=>(0,a.B6)(n.pathname,e)));if(!s)return null;const u=s.sidebar,c=u?r.docsSidebars[u]:void 0;return{docElement:(0,o.v)(i),sidebarName:u,sidebarItems:c}}},1003:(e,t,n)=>{"use strict";n.d(t,{e3:()=>p,be:()=>d,Jx:()=>h});var r=n(6540),a=n(4164),o=n(5260),i=n(3102);function s(){const e=r.useContext(i.o);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var l=n(6025),u=n(4586);var c=n(4848);function d(e){let{title:t,description:n,keywords:r,image:a,children:i}=e;const s=function(e){const{siteConfig:t}=(0,u.A)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,l.h)(),f=a?d(a,{absolute:!0}):void 0;return(0,c.jsxs)(o.A,{children:[t&&(0,c.jsx)("title",{children:s}),t&&(0,c.jsx)("meta",{property:"og:title",content:s}),n&&(0,c.jsx)("meta",{name:"description",content:n}),n&&(0,c.jsx)("meta",{property:"og:description",content:n}),r&&(0,c.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),f&&(0,c.jsx)("meta",{property:"og:image",content:f}),f&&(0,c.jsx)("meta",{name:"twitter:image",content:f}),i]})}const f=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const i=r.useContext(f),s=(0,a.A)(i,t);return(0,c.jsxs)(f.Provider,{value:s,children:[(0,c.jsx)(o.A,{children:(0,c.jsx)("html",{className:s})}),n]})}function h(e){let{children:t}=e;const n=s(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const o=`plugin-id-${n.plugin.id}`;return(0,c.jsx)(p,{className:(0,a.A)(r,o),children:t})}},9532:(e,t,n)=>{"use strict";n.d(t,{Be:()=>u,ZC:()=>s,_q:()=>i,dV:()=>l,fM:()=>c});var r=n(6540),a=n(205),o=n(4848);function i(e){const t=(0,r.useRef)(e);return(0,a.A)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function s(e){const t=(0,r.useRef)();return(0,a.A)((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function u(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function c(e){return t=>{let{children:n}=t;return(0,o.jsx)(o.Fragment,{children:e.reduceRight(((e,t)=>(0,o.jsx)(t,{children:e})),n)})}}},9169:(e,t,n)=>{"use strict";n.d(t,{Dt:()=>s,ys:()=>i});var r=n(6540),a=n(8328),o=n(4586);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,o.A)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.A,baseUrl:e})),[e])}},3104:(e,t,n)=>{"use strict";n.d(t,{Mq:()=>f,Tv:()=>u,gk:()=>p});var r=n(6540),a=n(8193),o=n(2303),i=(n(205),n(9532)),s=n(4848);const l=r.createContext(void 0);function u(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,s.jsx)(l.Provider,{value:n,children:t})}function c(){const e=(0,r.useContext)(l);if(null==e)throw new i.dV("ScrollControllerProvider");return e}const d=()=>a.A.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function f(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=c(),a=(0,r.useRef)(d()),o=(0,i._q)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=d();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function p(){const e=(0,r.useRef)(null),t=(0,o.A)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&at&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},2967:(e,t,n)=>{"use strict";n.d(t,{Cy:()=>r,tU:()=>a});n(4586);const r="default";function a(e,t){return`docs-${e}-${t}`}},9466:(e,t,n)=>{"use strict";n.d(t,{Wf:()=>l});n(6540);const r="localStorage";function a(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function o(e){if(void 0===e&&(e=r),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,i||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),i=!0),null}var t}let i=!1;const s={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function l(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=o(t?.persistence);return null===n?s:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),a({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),a({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}},2131:(e,t,n)=>{"use strict";n.d(t,{o:()=>i});var r=n(4586),a=n(6347),o=n(440);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:s}}=(0,r.A)(),{pathname:l}=(0,a.zy)(),u=(0,o.applyTrailingSlash)(l,{trailingSlash:n,baseUrl:e}),c=s===i?e:e.replace(`/${s}/`,"/"),d=u.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${c}`:`${c}${e}/`}(n)}${d}`}}}},5062:(e,t,n)=>{"use strict";n.d(t,{$:()=>i});var r=n(6540),a=n(6347),o=n(9532);function i(e){const t=(0,a.zy)(),n=(0,o.ZC)(t),i=(0,o._q)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6342:(e,t,n)=>{"use strict";n.d(t,{p:()=>a});var r=n(4586);function a(){return(0,r.A)().siteConfig.themeConfig}},2983:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},253:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},440:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(2983);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(253);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},2849:(e,t,n)=>{"use strict";n.d(t,{A:()=>i});n(6540);var r=n(5391);const a={loadingRing:"loadingRing_RJI3","loading-ring":"loading-ring_FB5o"};var o=n(4848);function i(e){let{className:t}=e;return(0,o.jsxs)("div",{className:(0,r.A)(a.loadingRing,t),children:[(0,o.jsx)("div",{}),(0,o.jsx)("div",{}),(0,o.jsx)("div",{}),(0,o.jsx)("div",{})]})}},5891:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s});var r=n(8291),a=n.n(r),o=n(1088);const i=new Map;function s(e,t){const n=`${e}${t}`;let r=i.get(n);return r||(r=async function(e,t){{const n=`${e}${o.IH.replace("{dir}",t?`-${t.replace(/\//g,"-")}`:"")}`;if(new URL(n,location.origin).origin!==location.origin)throw new Error("Unexpected version url");const r=await(await fetch(n)).json(),i=r.map(((e,t)=>{let{documents:n,index:r}=e;return{type:t,documents:n,index:a().Index.load(r)}})),s=r.reduce(((e,t)=>{for(const n of t.index.invertedIndex)/\p{Unified_Ideograph}/u.test(n[0][0])&&e.add(n[0]);return e}),new Set);return{wrappedIndexes:i,zhDictionary:Array.from(s)}}return{wrappedIndexes:[],zhDictionary:[]}}(e,t),i.set(n,r)),r}},2384:(e,t,n)=>{"use strict";n.d(t,{m:()=>l});var r=n(8291),a=n.n(r);var o=n(1088);function i(e){return s(e).concat(s(e.filter((e=>{const t=e[e.length-1];return!t.trailing&&t.maybeTyping})),!0))}function s(e,t){return e.map((e=>({tokens:e.map((e=>e.value)),term:e.map((e=>({value:e.value,presence:a().Query.presence.REQUIRED,wildcard:(t?e.trailing||e.maybeTyping:e.trailing)?a().Query.wildcard.TRAILING:a().Query.wildcard.NONE})))})))}function l(e,t,n){return function(r,s){const l=function(e,t){if(1===t.length&&["ja","jp","th"].includes(t[0]))return a()[t[0]].tokenizer(e).map((e=>e.toString()));let n=/[^-\s]+/g;return t.includes("zh")&&(n=/\w+|\p{Unified_Ideograph}+/gu),e.toLowerCase().match(n)||[]}(r,o.BH);if(0===l.length)return void s([]);const u=function(e,t){const n=function(e,t){const n=[];return function e(r,a){if(0===r.length)return void n.push(a);const o=r[0];if(/\p{Unified_Ideograph}/u.test(o)){const n=function(e,t){const n=[];return function e(r,a){let o=0,i=!1;for(const s of t)if(r.substr(0,s.length)===s){const t={missed:a.missed,term:a.term.concat({value:s})};r.length>s.length?e(r.substr(s.length),t):n.push(t),i=!0}else for(let t=s.length-1;t>o;t-=1){const l=s.substr(0,t);if(r.substr(0,t)===l){o=t;const s={missed:a.missed,term:a.term.concat({value:l,trailing:!0})};r.length>t?e(r.substr(t),s):n.push(s),i=!0;break}}i||(r.length>0?e(r.substr(1),{missed:a.missed+1,term:a.term}):a.term.length>0&&n.push(a))}(e,{missed:0,term:[]}),n.sort(((e,t)=>{const n=e.missed>0?1:0,r=t.missed>0?1:0;return n!==r?n-r:e.term.length-t.term.length})).map((e=>e.term))}(o,t);for(const t of n){const n=a.concat(...t);e(r.slice(1),n)}}else{const t=a.concat({value:o});e(r.slice(1),t)}}(e,[]),n}(e,t);if(0===n.length)return[{tokens:e,term:e.map((e=>({value:e,presence:a().Query.presence.REQUIRED,wildcard:a().Query.wildcard.LEADING|a().Query.wildcard.TRAILING})))}];for(const a of n)a[a.length-1].maybeTyping=!0;const r=[];for(const i of o.BH)if("en"===i)o.sx||r.unshift(a().stopWordFilter);else{const e=a()[i];e.stopWordFilter&&r.unshift(e.stopWordFilter)}let s;if(r.length>0){const e=e=>r.reduce(((e,t)=>e.filter((e=>t(e.value)))),e);s=[];const t=[];for(const r of n){const n=e(r);s.push(n),n.length0&&t.push(n)}n.push(...t)}else s=n.slice();const l=[];for(const a of s)if(a.length>2)for(let e=a.length-1;e>=0;e-=1)l.push(a.slice(0,e).concat(a.slice(e+1)));return i(n).concat(i(l))}(l,t),c=[];e:for(const{term:t,tokens:a}of u)for(const{documents:r,index:o,type:i}of e)if(c.push(...o.query((e=>{for(const n of t)e.term(n.value,{wildcard:n.wildcard,presence:n.presence})})).slice(0,n).filter((e=>!c.some((t=>t.document.i.toString()===e.ref)))).slice(0,n-c.length).map((t=>{const n=r.find((e=>e.i.toString()===t.ref));return{document:n,type:i,page:0!==i&&e[0].documents.find((e=>e.i===n.p)),metadata:t.matchData.metadata,tokens:a,score:t.score}}))),c.length>=n)break e;!function(e){e.forEach(((e,t)=>{e.index=t})),e.sort(((t,n)=>{let r=t.type>0&&t.page?e.findIndex((e=>e.document===t.page)):t.index,a=n.type>0&&n.page?e.findIndex((e=>e.document===n.page)):n.index;return-1===r&&(r=t.index),-1===a&&(a=n.index),r===a?0===t.type?-1:0===n.type?1:t.index-n.index:r-a}))}(c),function(e){e.forEach(((t,n)=>{n>0&&t.page&&e.some((e=>e.document===t.page))&&(n{"use strict";function r(e){return e.join(" \u203a ")}n.d(t,{$:()=>r})},3103:(e,t,n)=>{"use strict";function r(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}n.d(t,{Z:()=>r})},7674:(e,t,n)=>{"use strict";function r(e,t){const n=[];for(const r of Object.values(e))r[t]&&n.push(...r[t].position);return n.sort(((e,t)=>e[0]-t[0]||t[1]-e[1]))}n.d(t,{g:()=>r})},6841:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(3103);function a(e,t,n){const o=[];for(const i of t){const n=e.toLowerCase().indexOf(i);if(n>=0){n>0&&o.push(a(e.substr(0,n),t)),o.push(`${(0,r.Z)(e.substr(n,i.length))}`);const s=n+i.length;s${(0,r.Z)(e)}`:(0,r.Z)(e):o.join("")}},3810:(e,t,n)=>{"use strict";n.d(t,{C:()=>l});var r=n(3103),a=n(6841);const o=/\w+|\p{Unified_Ideograph}/u;function i(e){const t=[];let n=0,r=e;for(;r.length>0;){const a=r.match(o);if(!a){t.push(r);break}a.index>0&&t.push(r.substring(0,a.index)),t.push(a[0]),n+=a.index+a[0].length,r=e.substring(n)}return t}var s=n(1088);function l(e,t,n,o){void 0===o&&(o=s.rG);const{chunkIndex:l,chunks:u}=function(e,t,n){const o=[];let s=0,l=0,u=-1;for(;sl){const t=i(e.substring(l,c)).map((e=>({html:(0,r.Z)(e),textLength:e.length})));for(const e of t)o.push(e)}-1===u&&(u=o.length),l=c+d,o.push({html:(0,a.Z)(e.substring(c,l),n,!0),textLength:d})}}if(l({html:(0,r.Z)(e),textLength:e.length})));for(const e of t)o.push(e)}return{chunkIndex:u,chunks:o}}(e,t,n),c=u.slice(0,l),d=u[l],f=[d.html],p=u.slice(l+1);let h=d.textLength,g=0,m=0,y=!1,b=!1;for(;h0){const e=c.pop();h+e.textLength<=o?(f.unshift(e.html),g+=e.textLength,h+=e.textLength):(y=!0,c.length=0)}else{if(!(p.length>0))break;{const e=p.shift();h+e.textLength<=o?(f.push(e.html),m+=e.textLength,h+=e.textLength):(b=!0,p.length=0)}}return(y||c.length>0)&&f.unshift("\u2026"),(b||p.length>0)&&f.push("\u2026"),f.join("")}},3385:(e,t,n)=>{"use strict";function r(e,t){if("string"==typeof e)return{label:e,path:e};{const{label:n,path:r}=e;return"string"==typeof n?{label:n,path:r}:Object.prototype.hasOwnProperty.call(n,t)?{label:n[t],path:r}:{label:r,path:r}}}n.d(t,{p:()=>r})},1088:(e,t,n)=>{"use strict";n.d(t,{CU:()=>o,UB:()=>p,tb:()=>u,O6:()=>m,I$:()=>h,BH:()=>r,sx:()=>a,ZG:()=>f,WW:()=>c,pk:()=>d,Hg:()=>g,IH:()=>i,rG:()=>l,AT:()=>s,dz:()=>y});n(8291);const r=["en"],a=!1,o=null,i="search-index{dir}.json",s=8,l=50,u=!1,c=!0,d=!0,f="right",p=void 0,h=!0,g=null,m=!1,y=!1},1513:(e,t,n)=>{"use strict";n.d(t,{zR:()=>w,TM:()=>C,yJ:()=>p,sC:()=>A,AO:()=>f});var r=n(8168);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;f--){var p=i[f];"."===p?o(i,f):".."===p?(o(i,f),d++):d&&(o(i,f),d--)}if(!u)for(;d--;d)i.unshift("..");!u||""===i[0]||i[0]&&a(i[0])||i.unshift("");var h=i.join("/");return n&&"/"!==h.substr(-1)&&(h+="/"),h};var s=n(1561);function l(e){return"/"===e.charAt(0)?e:"/"+e}function u(e){return"/"===e.charAt(0)?e.substr(1):e}function c(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function f(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function p(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.A)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function h(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=p(e,t,g(),w.location);c.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(4363),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function l(e){return r.isMemo(e)?i:s[e.$$typeof]||a}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=i;var u=Object.defineProperty,c=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,h=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(h){var a=p(n);a&&a!==h&&e(t,a,r)}var i=c(n);d&&(i=i.concat(d(n)));for(var s=l(t),g=l(n),m=0;m{"use strict";e.exports=function(e,t,n,r,a,o,i,s){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,r,a,o,i,s],c=0;(l=new Error(t.replace(/%s/g,(function(){return u[c++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},4634:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},8291:(e,t,n)=>{var r,a;!function(){var o,i,s,l,u,c,d,f,p,h,g,m,y,b,v,w,x,k,S,E,_,C,T,A,L,P,N,j,O,I,R=function(e){var t=new R.Builder;return t.pipeline.add(R.trimmer,R.stopWordFilter,R.stemmer),t.searchPipeline.add(R.stemmer),e.call(t,t),t.build()};R.version="2.3.9",R.utils={},R.utils.warn=(o=this,function(e){o.console&&console.warn&&console.warn(e)}),R.utils.asString=function(e){return null==e?"":e.toString()},R.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),n=Object.keys(e),r=0;r0){var l=R.utils.clone(t)||{};l.position=[i,s],l.index=a.length,a.push(new R.Token(n.slice(i,o),l))}i=o+1}}return a},R.tokenizer.separator=/[\s\-]+/,R.Pipeline=function(){this._stack=[]},R.Pipeline.registeredFunctions=Object.create(null),R.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&R.utils.warn("Overwriting existing registered function: "+t),e.label=t,R.Pipeline.registeredFunctions[e.label]=e},R.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||R.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},R.Pipeline.load=function(e){var t=new R.Pipeline;return e.forEach((function(e){var n=R.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)})),t},R.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach((function(e){R.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},R.Pipeline.prototype.after=function(e,t){R.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},R.Pipeline.prototype.before=function(e,t){R.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},R.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},R.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n1&&(oe&&(n=a),o!=e);)r=n-t,a=t+Math.floor(r/2),o=this.elements[2*a];return o==e||o>e?2*a:os?u+=2:i==s&&(t+=n[l+1]*r[u+1],l+=2,u+=2);return t},R.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},R.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t0){var o,i=a.str.charAt(0);i in a.node.edges?o=a.node.edges[i]:(o=new R.TokenSet,a.node.edges[i]=o),1==a.str.length&&(o.final=!0),r.push({node:o,editsRemaining:a.editsRemaining,str:a.str.slice(1)})}if(0!=a.editsRemaining){if("*"in a.node.edges)var s=a.node.edges["*"];else{s=new R.TokenSet;a.node.edges["*"]=s}if(0==a.str.length&&(s.final=!0),r.push({node:s,editsRemaining:a.editsRemaining-1,str:a.str}),a.str.length>1&&r.push({node:a.node,editsRemaining:a.editsRemaining-1,str:a.str.slice(1)}),1==a.str.length&&(a.node.final=!0),a.str.length>=1){if("*"in a.node.edges)var l=a.node.edges["*"];else{l=new R.TokenSet;a.node.edges["*"]=l}1==a.str.length&&(l.final=!0),r.push({node:l,editsRemaining:a.editsRemaining-1,str:a.str.slice(1)})}if(a.str.length>1){var u,c=a.str.charAt(0),d=a.str.charAt(1);d in a.node.edges?u=a.node.edges[d]:(u=new R.TokenSet,a.node.edges[d]=u),1==a.str.length&&(u.final=!0),r.push({node:u,editsRemaining:a.editsRemaining-1,str:c+a.str.slice(2)})}}}return n},R.TokenSet.fromString=function(e){for(var t=new R.TokenSet,n=t,r=0,a=e.length;r=e;t--){var n=this.uncheckedNodes[t],r=n.child.toString();r in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[r]:(n.child._str=r,this.minimizedNodes[r]=n.child),this.uncheckedNodes.pop()}},R.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},R.Index.prototype.search=function(e){return this.query((function(t){new R.QueryParser(e,t).parse()}))},R.Index.prototype.query=function(e){for(var t=new R.Query(this.fields),n=Object.create(null),r=Object.create(null),a=Object.create(null),o=Object.create(null),i=Object.create(null),s=0;s1?1:e},R.Builder.prototype.k1=function(e){this._k1=e},R.Builder.prototype.add=function(e,t){var n=e[this._ref],r=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var a=0;a=this.length)return R.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},R.QueryLexer.prototype.width=function(){return this.pos-this.start},R.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},R.QueryLexer.prototype.backup=function(){this.pos-=1},R.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=R.QueryLexer.EOS&&this.backup()},R.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(R.QueryLexer.TERM)),e.ignore(),e.more())return R.QueryLexer.lexText},R.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(R.QueryLexer.EDIT_DISTANCE),R.QueryLexer.lexText},R.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(R.QueryLexer.BOOST),R.QueryLexer.lexText},R.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(R.QueryLexer.TERM)},R.QueryLexer.termSeparator=R.tokenizer.separator,R.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==R.QueryLexer.EOS)return R.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return R.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(R.QueryLexer.TERM),R.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(R.QueryLexer.TERM),R.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(R.QueryLexer.PRESENCE),R.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(R.QueryLexer.PRESENCE),R.QueryLexer.lexText;if(t.match(R.QueryLexer.termSeparator))return R.QueryLexer.lexTerm}else e.escapeCharacter()}},R.QueryParser=function(e,t){this.lexer=new R.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},R.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=R.QueryParser.parseClause;e;)e=e(this);return this.query},R.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},R.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},R.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},R.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case R.QueryLexer.PRESENCE:return R.QueryParser.parsePresence;case R.QueryLexer.FIELD:return R.QueryParser.parseField;case R.QueryLexer.TERM:return R.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new R.QueryParseError(n,t.start,t.end)}},R.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=R.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=R.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new R.QueryParseError(n,t.start,t.end)}var r=e.peekLexeme();if(null==r){n="expecting term or field, found nothing";throw new R.QueryParseError(n,t.start,t.end)}switch(r.type){case R.QueryLexer.FIELD:return R.QueryParser.parseField;case R.QueryLexer.TERM:return R.QueryParser.parseTerm;default:n="expecting term or field, found '"+r.type+"'";throw new R.QueryParseError(n,r.start,r.end)}}},R.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),r="unrecognised field '"+t.str+"', possible fields: "+n;throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.fields=[t.str];var a=e.peekLexeme();if(null==a){r="expecting term, found nothing";throw new R.QueryParseError(r,t.start,t.end)}if(a.type===R.QueryLexer.TERM)return R.QueryParser.parseTerm;r="expecting term, found '"+a.type+"'";throw new R.QueryParseError(r,a.start,a.end)}},R.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(null!=n)switch(n.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+n.type+"'";throw new R.QueryParseError(r,n.start,n.end)}else e.nextClause()}},R.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="edit distance must be numeric";throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.editDistance=n;var a=e.peekLexeme();if(null!=a)switch(a.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+a.type+"'";throw new R.QueryParseError(r,a.start,a.end)}else e.nextClause()}},R.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="boost must be numeric";throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.boost=n;var a=e.peekLexeme();if(null!=a)switch(a.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+a.type+"'";throw new R.QueryParseError(r,a.start,a.end)}else e.nextClause()}},void 0===(a="function"==typeof(r=function(){return R})?r.call(t,n,t,e):r)||(e.exports=a)}()},119:(e,t,n)=>{"use strict";n.r(t)},1043:(e,t,n)=>{"use strict";n.r(t)},5947:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),u=o.querySelector(r.barSelector),c=r.speed,d=r.easing;return o.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),l(u,i(e,c,d)),1===e?(l(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){l(o,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),c)}),c)):setTimeout(t,c)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");c(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),s=e?"-100":o(n.status||0),u=document.querySelector(r.parent);return l(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&p(a),u!=document.body&&c(u,"nprogress-custom-parent"),u.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),l=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function u(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=f(e),r=n+t;u(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);u(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},5302:(e,t,n)=>{var r=n(4634);e.exports=p,e.exports.parse=o,e.exports.compile=function(e,t){return s(o(e,t),t)},e.exports.tokensToFunction=s,e.exports.tokensToRegExp=f;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,i=0,s="",c=t&&t.delimiter||"/";null!=(n=a.exec(e));){var d=n[0],f=n[1],p=n.index;if(s+=e.slice(i,p),i=p+d.length,f)s+=f[1];else{var h=e[i],g=n[2],m=n[3],y=n[4],b=n[5],v=n[6],w=n[7];s&&(r.push(s),s="");var x=null!=g&&null!=h&&h!==g,k="+"===v||"*"===v,S="?"===v||"*"===v,E=n[2]||c,_=y||b;r.push({name:m||o++,prefix:g||"",delimiter:E,optional:S,repeat:k,partial:x,asterisk:!!w,pattern:_?u(_):w?".*":"[^"+l(E)+"]+?"})}}return i{Prism.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},Prism.languages.webmanifest=Prism.languages.json},64:()=>{Prism.languages.lua={comment:/^#!.+|--(?:\[(=*)\[[\s\S]*?\]\1\]|.*)/m,string:{pattern:/(["'])(?:(?!\1)[^\\\r\n]|\\z(?:\r\n|\s)|\\(?:\r\n|[^z]))*\1|\[(=*)\[[\s\S]*?\]\2\]/,greedy:!0},number:/\b0x[a-f\d]+(?:\.[a-f\d]*)?(?:p[+-]?\d+)?\b|\b\d+(?:\.\B|(?:\.\d*)?(?:e[+-]?\d+)?\b)|\B\.\d+(?:e[+-]?\d+)?\b/i,keyword:/\b(?:and|break|do|else|elseif|end|false|for|function|goto|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,function:/(?!\d)\w+(?=\s*(?:[({]))/,operator:[/[-+*%^&|#]|\/\/?|<[<=]?|>[>=]?|[=~]=?/,{pattern:/(^|[^.])\.\.(?!\.)/,lookbehind:!0}],punctuation:/[\[\](){},;]|\.+|:+/}},9700:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,s=i.length;-1!==n.code.indexOf(a=t(r,s));)++s;return i[s]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(s){for(var l=0;l=o.length);l++){var u=s[l];if("string"==typeof u||u.content&&"string"==typeof u.content){var c=o[a],d=n.tokenStack[c],f="string"==typeof u?u:u.content,p=t(r,c),h=f.indexOf(p);if(h>-1){++a;var g=f.substring(0,h),m=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),y=f.substring(h+p.length),b=[];g&&b.push.apply(b,i([g])),b.push(m),y&&b.push.apply(b,i([y])),"string"==typeof u?s.splice.apply(s,[l,1].concat(b)):u.content=b}}else u.content&&i(u.content)}return s}(n.tokens)}}}})}(Prism)},2719:(e,t,n)=>{var r={"./prism-json":2514,"./prism-lua":64};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=2719},2694:(e,t,n)=>{"use strict";var r=n(6925);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5556:(e,t,n)=>{e.exports=n(2694)()},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},2551:(e,t,n)=>{"use strict";var r=n(6540),a=n(9982);function o(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n