diff --git a/404.html b/404.html index f2d0a096..bc4c35ae 100644 --- a/404.html +++ b/404.html @@ -9,13 +9,13 @@ - +
Skip to main content

Page Not Found

This page no longer exists. It may have moved, or its content is no longer supported by Regression Games.

- + \ No newline at end of file diff --git a/assets/js/1df93b7f.02880ffe.js b/assets/js/1df93b7f.02880ffe.js deleted file mode 100644 index 1be4beb3..00000000 --- a/assets/js/1df93b7f.02880ffe.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkregression_docs=self.webpackChunkregression_docs||[]).push([[3237],{8391:(A,e,t)=>{t.r(e),t.d(e,{default:()=>g});var a=t(7294),l=t(6010),c=t(9960),s=t(7961),E=t(7462);const B={features:"features_t9lD",featureSvg:"featureSvg_GfXr"},n=[{title:"A Plethora of Features",image:t(3768).Z,description:a.createElement(a.Fragment,null,"Regression Games is building the best platform for AI agent development with replay features, validation libraries, CI/CD integration, and more.")},{title:"Ease of Integration",image:t(4661).Z,description:a.createElement(a.Fragment,null,"Whether you are building an MMORPG or a simple 2D platformer, the Regression Games SDK follows a simple integration pattern to get you up and running quickly.")},{title:"Bot Versatility",image:t(7390).Z,description:a.createElement(a.Fragment,null,"Bots on Regression Games can click through menus, control spawned characters, play test with humans, validate behaviors, and more.")}];function r(A){let{title:e,image:t,description:c}=A;return a.createElement("div",{className:(0,l.Z)("col col--4")},a.createElement("div",{className:"text--center"},a.createElement("img",{className:B.featureSvg,src:t})),a.createElement("div",{className:"text--center padding-horiz--md"},a.createElement("h3",null,e),a.createElement("p",null,c)))}function Q(){return a.createElement("section",{className:B.features},a.createElement("div",{className:"container"},a.createElement("div",{className:"row"},n.map(((A,e)=>a.createElement(r,(0,E.Z)({key:e},A)))))))}const i="heroBanner_qdFl",o="buttons_AeoN",m=()=>a.createElement("header",{className:(0,l.Z)("hero hero--secondary",i)},a.createElement("div",{className:"container",style:{textAlign:"left"}},a.createElement("div",{className:"row"},a.createElement("div",{className:"col margin-vert--lg margin-right--md"},a.createElement("h1",{className:"hero__title"},"Improve quality and reduce costs with AI agents"),a.createElement("p",{className:"hero__subtitle"},"Regression Games helps game developers go from zero to one with AI agent development"),a.createElement("div",{className:o,style:{justifyContent:"left"}},a.createElement(c.Z,{className:"button button--primary button--outline button--lg",to:"tutorials/building-your-first-bot"},"Get Started"),a.createElement(c.Z,{className:"button button--secondary button--lg margin-left--md",to:"overview"},"Full Reference"))),a.createElement("div",{className:"col"},a.createElement("img",{src:t(329).Z,alt:"Regression Games",style:{borderRadius:"12px"}}),a.createElement("div",{style:{color:"gray",paddingRight:"24px",fontStyle:"italic"}},"Demo of bots validating abilities in ",a.createElement("a",{href:"https://unity.com/demos/small-scale-coop-sample",target:"_blank"},"Boss Room")," (created by Unity), the timeline feature, and the automated Agent Builder."))))),g=()=>a.createElement(s.Z,{title:"Regression Games Docs",description:"Build bots for games"},a.createElement(m,null),a.createElement("main",null,a.createElement(Q,null)),a.createElement("div",{className:"container text--center"},a.createElement("div",{style:{marginBottom:"64px",marginTop:"32px",fontSize:"1.5em",color:"grey",fontWeight:"bold"}},"BACKED BY TIER 1 INVESTORS"),a.createElement("div",{className:"row"},a.createElement("div",{className:(0,l.Z)("col col--3")},a.createElement("div",{className:"text--center"},a.createElement("a",{href:"https://nea.com/",target:"_blank"},a.createElement("img",{style:{height:"60px"},src:t(8926).Z})))),a.createElement("div",{className:(0,l.Z)("col col--3")},a.createElement("div",{className:"text--center"},a.createElement("a",{href:"https://a16z.com/",target:"_blank"},a.createElement("img",{style:{height:"100px",marginTop:"-20px"},src:t(2074).Z})))),a.createElement("div",{className:(0,l.Z)("col col--3")},a.createElement("div",{className:"text--center"},a.createElement("a",{href:"https://roosh.vc/",target:"_blank"},a.createElement("img",{style:{height:"150px",marginTop:"-40px"},src:t(5377).Z})))),a.createElement("div",{className:(0,l.Z)("col col--3")},a.createElement("div",{className:"text--center"},a.createElement("a",{href:"https://bbq.capital/",target:"_blank"},a.createElement("img",{style:{height:"80px",marginTop:"-00px"},src:t(6796).Z})))))))},2074:(A,e,t)=>{t.d(e,{Z:()=>a});const a=t.p+"assets/images/a16z-137749dc988bf598433d91265cf02959.jpeg"},7390:(A,e,t)=>{t.d(e,{Z:()=>a});const a=t.p+"assets/images/ai (2)-19c3966e89df8c194ecd3e781a68cfca.png"},4661:(A,e,t)=>{t.d(e,{Z:()=>a});const a=t.p+"assets/images/ai (3)-a8825fb481555ca2707f39c89be6dedb.png"},3768:(A,e,t)=>{t.d(e,{Z:()=>a});const a=t.p+"assets/images/ai_1-e765bdc2cfecce91cbd44170e21a6e1c.png"},6796:(A,e,t)=>{t.d(e,{Z:()=>a});const a="data:image/jpeg;base64,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zzzzyj73333jzzzzzzy1z333zTzzzzzzetX/AN9e888887+2rUi9888887OMMMMdO888887288888U888888528888o8888888s/es+t88888888888888888888888888888//EACYRAQABAwMCBgMAAAAAAAAAAAERADFhICFBUYEQMHGhwdFAkbH/2gAIAQMBAT8Q/ChAGWKSY9l90ZBGEf55UxApe4+3q7et6lLWWfAmpHIw0c3z9j16mb+tARJHXMmM8Lhg5nHFIjDpcWz8j5O/kHOAr9+vepOOJ8lz+Z0LyAP37eROVwu57duiBQ/ywHflwG7gpNKU4TwiWkZtDCLM0AiiCIu60vCwwMLHhegieDVuZejsW7nHSaGjeDjomRhMlRcWdmxhIB5Gm8lL1k+Q3yhQgYYARE2Q7IFx5Wp9qjfStxLodyLGACaIugy9IN3ezNu+phHqUlyKyqytZWsqkkLSANTgOKAhZ1Ko8a5XBQCR0hHJ5C8ugclK4pdn9UZAmpB+c//EACkRAQABAQYFBAMBAAAAAAAAAAERACAhMUFhwTBRgZGhcdHh8BBAsfH/2gAIAQIBAT8Q/SKlA1qJjyFCyCaM8KY3rn7Pepll1/EmEdKcL4+r/vehAJhbkUicYxjT1pEYbKLJruNzrwDpMcxj81Lw1Dcy/mthB8keAAsDFzjH40rCiE09KNhjDS7U8zR8McHJ/JQDakiyjd6HmKxPlP31pY7gLY3elRCZbs9/C1IryTd6viKlhAXk4JmevegwmGXlBr4tNIZI7b0q42S7CkU5Ad/8tYBSRTgby0LDLefa2Qy/mnRwlnQxPXgBxJ/e9Jbw9Sfaht+9I3avmR5t/wAVdUuUT2vK59sXn+9//8QAKhABAAECBAUDBAMAAAAAAAAAAREAITAxQVFhcYHB8BCRoSBAYOGx0fH/2gAIAQEAAT8Q/FgBbaX8sqJl82yaNk4HuqFUYzhTrKkRRITR+zu5dwbHhd+aERj9NodD6WA40EHovSZzu5Dlp8GnKEQiQjjgqASuhRdHsFuMavDT+MAaBFgW4f7UgBmxYwqXDZZp5j/MNxncQX7jb94x4gR+QsSZnz0oWySuRODhit8wMjQ79cactWbrnHcvVoa2vucNHWhEkuYIEEqJwLfBfb7ByGNeQODmfxwoiWNeF5OvlsDMObySKRlZGHFzvSvl6ijJZppQ8TscNXJqMkSbLnHct9ZBMgz3cWcCOnGh5vUBI9v29IQJ63sVOFNpxNTzalbJK4R51LnkRQeZk+Z0KVyeJzNPoNRAStO5m3ucSIk+37dfSEE9eNTzb0lgjp2x6RWj2/bpUsE9e2KJPLUp1CIlCTqUOapXI9fQZ+EcyzvPTFjBHTjQ839YdA6Y/b49ZwptOJqebVARH6s9EkqWY4q5bJ8b1GAW0lznp196MTdI2lLPZXqYd3NJgiypsa8l7V592rz7tXn3avHu1efdq8+7V592rz7tXn3avPu1Oebn/XXkvamkYpALWAcVhzxVw3hWcD/UxcoUJAJV5BQ8oEZhRw02LEVxHmXDQeKNYMJyB4kBv0XdiAPYvCFxHRp3Uw4EK0NizSYasRKUjBNoXoAMkUvAxBBKDwJ7xoZy0bZKOq0B46hmiRVxMNOTGBLqtEgOiFIWEqQN4OCEnBxVTgVk0J7xGQL2ESKOKZhsdJcthK0XDfwIsypDcVs8cZg7SngJNHUydajccrK3SF5NdQEnJ2b7oqvQKBL1TS4RzAPdrMFquloroUT/AMjnMhlyjO5TWvlX0oSq5xnYGKP5gBdlOSO8MtqW2rZkN7oip/WX+IQWg3AbraSqVVW6v5V//9k="},329:(A,e,t)=>{t.d(e,{Z:()=>a});const a=t.p+"assets/images/demo-2f7941b1086f75493d0cba4a1d73ffcc.gif"},8926:(A,e,t)=>{t.d(e,{Z:()=>a});const a=t.p+"assets/images/nea-3a1bcf8f2def3c2af15a50c315f2f176.jpg"},5377:(A,e,t)=>{t.d(e,{Z:()=>a});const a="data:image/jpeg;base64,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"}}]); \ No newline at end of file diff --git a/assets/js/1df93b7f.8b9d886a.js b/assets/js/1df93b7f.8b9d886a.js new file mode 100644 index 00000000..eea5f244 --- /dev/null +++ b/assets/js/1df93b7f.8b9d886a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkregression_docs=self.webpackChunkregression_docs||[]).push([[3237],{8391:(A,e,t)=>{t.r(e),t.d(e,{default:()=>g});var a=t(7294),l=t(6010),c=t(9960),s=t(7961),n=t(7462);const E={features:"features_t9lD",featureSvg:"featureSvg_GfXr"},r=[{title:"A Plethora of Features",image:t(3768).Z,description:a.createElement(a.Fragment,null,"Regression Games is building the best platform for AI agent development with replay features, validation libraries, CI/CD integration, and more.")},{title:"Ease of Integration",image:t(4661).Z,description:a.createElement(a.Fragment,null,"Whether you are building an MMORPG or a simple 2D platformer, the Regression Games SDK follows a simple integration pattern to get you up and running quickly.")},{title:"Bot Versatility",image:t(7390).Z,description:a.createElement(a.Fragment,null,"Bots on Regression Games can click through menus, control spawned characters, play test with humans, validate behaviors, and more.")}];function B(A){let{title:e,image:t,description:c}=A;return a.createElement("div",{className:(0,l.Z)("col col--4")},a.createElement("div",{className:"text--center"},a.createElement("img",{className:E.featureSvg,src:t})),a.createElement("div",{className:"text--center padding-horiz--md"},a.createElement("h3",null,e),a.createElement("p",null,c)))}function i(){return a.createElement("section",{className:E.features},a.createElement("div",{className:"container"},a.createElement("div",{className:"row"},r.map(((A,e)=>a.createElement(B,(0,n.Z)({key:e},A)))))))}const o="heroBanner_qdFl",m="buttons_AeoN",Q=()=>a.createElement("header",{className:(0,l.Z)("hero hero--secondary",o)},a.createElement("div",{className:"container",style:{textAlign:"left"}},a.createElement("div",{className:"row"},a.createElement("div",{className:"col margin-vert--lg margin-right--md"},a.createElement("h1",{className:"hero__title"},"Improve quality and reduce costs with AI agents"),a.createElement("p",{className:"hero__subtitle"},"Regression Games helps game developers go from zero to one with AI agent development"),a.createElement("div",{className:m,style:{justifyContent:"left"}},a.createElement(c.Z,{className:"button button--primary button--outline button--lg",to:"tutorials/building-your-first-bot"},"Get Started"),a.createElement(c.Z,{className:"button button--secondary button--lg margin-left--md",to:"overview"},"Full Reference")),a.createElement("div",{style:{marginTop:"16px"}},"Get started immediately by adding the package to Unity:",a.createElement("div",{style:{marginTop:"16px",fontSize:12}},a.createElement("pre",{style:{display:"inline"}},"https://github.com/Regression-Games/RGUnityBots.git?path=src/gg.regression.unity.bots#v0.0.16")))),a.createElement("div",{className:"col"},a.createElement("img",{src:t(329).Z,alt:"Regression Games",style:{borderRadius:"12px"}}),a.createElement("div",{style:{color:"gray",paddingRight:"24px",fontStyle:"italic"}},"Demo of bots validating abilities in ",a.createElement("a",{href:"https://unity.com/demos/small-scale-coop-sample",target:"_blank"},"Boss Room")," (created by Unity), the timeline feature, and the automated Agent Builder."))))),g=()=>a.createElement(s.Z,{title:"Regression Games Docs",description:"Build bots for games"},a.createElement(Q,null),a.createElement("main",null,a.createElement(i,null)),a.createElement("div",{className:"container text--center"},a.createElement("div",{style:{marginBottom:"64px",marginTop:"32px",fontSize:"1.5em",color:"grey",fontWeight:"bold"}},"BACKED BY TIER 1 INVESTORS"),a.createElement("div",{className:"row"},a.createElement("div",{className:(0,l.Z)("col col--3")},a.createElement("div",{className:"text--center"},a.createElement("a",{href:"https://nea.com/",target:"_blank"},a.createElement("img",{style:{height:"60px"},src:t(8926).Z})))),a.createElement("div",{className:(0,l.Z)("col col--3")},a.createElement("div",{className:"text--center"},a.createElement("a",{href:"https://a16z.com/",target:"_blank"},a.createElement("img",{style:{height:"100px",marginTop:"-20px"},src:t(2074).Z})))),a.createElement("div",{className:(0,l.Z)("col col--3")},a.createElement("div",{className:"text--center"},a.createElement("a",{href:"https://roosh.vc/",target:"_blank"},a.createElement("img",{style:{height:"150px",marginTop:"-40px"},src:t(5377).Z})))),a.createElement("div",{className:(0,l.Z)("col col--3")},a.createElement("div",{className:"text--center"},a.createElement("a",{href:"https://bbq.capital/",target:"_blank"},a.createElement("img",{style:{height:"80px",marginTop:"-00px"},src:t(6796).Z})))))))},2074:(A,e,t)=>{t.d(e,{Z:()=>a});const a=t.p+"assets/images/a16z-137749dc988bf598433d91265cf02959.jpeg"},7390:(A,e,t)=>{t.d(e,{Z:()=>a});const a=t.p+"assets/images/ai (2)-19c3966e89df8c194ecd3e781a68cfca.png"},4661:(A,e,t)=>{t.d(e,{Z:()=>a});const a=t.p+"assets/images/ai (3)-a8825fb481555ca2707f39c89be6dedb.png"},3768:(A,e,t)=>{t.d(e,{Z:()=>a});const a=t.p+"assets/images/ai_1-e765bdc2cfecce91cbd44170e21a6e1c.png"},6796:(A,e,t)=>{t.d(e,{Z:()=>a});const a="data:image/jpeg;base64,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zzzzyj73333jzzzzzzy1z333zTzzzzzzetX/AN9e888887+2rUi9888887OMMMMdO888887288888U888888528888o8888888s/es+t88888888888888888888888888888//EACYRAQABAwMCBgMAAAAAAAAAAAERADFhICFBUYEQMHGhwdFAkbH/2gAIAQMBAT8Q/ChAGWKSY9l90ZBGEf55UxApe4+3q7et6lLWWfAmpHIw0c3z9j16mb+tARJHXMmM8Lhg5nHFIjDpcWz8j5O/kHOAr9+vepOOJ8lz+Z0LyAP37eROVwu57duiBQ/ywHflwG7gpNKU4TwiWkZtDCLM0AiiCIu60vCwwMLHhegieDVuZejsW7nHSaGjeDjomRhMlRcWdmxhIB5Gm8lL1k+Q3yhQgYYARE2Q7IFx5Wp9qjfStxLodyLGACaIugy9IN3ezNu+phHqUlyKyqytZWsqkkLSANTgOKAhZ1Ko8a5XBQCR0hHJ5C8ugclK4pdn9UZAmpB+c//EACkRAQABAQYFBAMBAAAAAAAAAAERACAhMUFhwTBRgZGhcdHh8BBAsfH/2gAIAQIBAT8Q/SKlA1qJjyFCyCaM8KY3rn7Pepll1/EmEdKcL4+r/vehAJhbkUicYxjT1pEYbKLJruNzrwDpMcxj81Lw1Dcy/mthB8keAAsDFzjH40rCiE09KNhjDS7U8zR8McHJ/JQDakiyjd6HmKxPlP31pY7gLY3elRCZbs9/C1IryTd6viKlhAXk4JmevegwmGXlBr4tNIZI7b0q42S7CkU5Ad/8tYBSRTgby0LDLefa2Qy/mnRwlnQxPXgBxJ/e9Jbw9Sfaht+9I3avmR5t/wAVdUuUT2vK59sXn+9//8QAKhABAAECBAUDBAMAAAAAAAAAAREAITAxQVFhcYHB8BCRoSBAYOGx0fH/2gAIAQEAAT8Q/FgBbaX8sqJl82yaNk4HuqFUYzhTrKkRRITR+zu5dwbHhd+aERj9NodD6WA40EHovSZzu5Dlp8GnKEQiQjjgqASuhRdHsFuMavDT+MAaBFgW4f7UgBmxYwqXDZZp5j/MNxncQX7jb94x4gR+QsSZnz0oWySuRODhit8wMjQ79cactWbrnHcvVoa2vucNHWhEkuYIEEqJwLfBfb7ByGNeQODmfxwoiWNeF5OvlsDMObySKRlZGHFzvSvl6ijJZppQ8TscNXJqMkSbLnHct9ZBMgz3cWcCOnGh5vUBI9v29IQJ63sVOFNpxNTzalbJK4R51LnkRQeZk+Z0KVyeJzNPoNRAStO5m3ucSIk+37dfSEE9eNTzb0lgjp2x6RWj2/bpUsE9e2KJPLUp1CIlCTqUOapXI9fQZ+EcyzvPTFjBHTjQ839YdA6Y/b49ZwptOJqebVARH6s9EkqWY4q5bJ8b1GAW0lznp196MTdI2lLPZXqYd3NJgiypsa8l7V592rz7tXn3avHu1efdq8+7V592rz7tXn3avPu1Oebn/XXkvamkYpALWAcVhzxVw3hWcD/UxcoUJAJV5BQ8oEZhRw02LEVxHmXDQeKNYMJyB4kBv0XdiAPYvCFxHRp3Uw4EK0NizSYasRKUjBNoXoAMkUvAxBBKDwJ7xoZy0bZKOq0B46hmiRVxMNOTGBLqtEgOiFIWEqQN4OCEnBxVTgVk0J7xGQL2ESKOKZhsdJcthK0XDfwIsypDcVs8cZg7SngJNHUydajccrK3SF5NdQEnJ2b7oqvQKBL1TS4RzAPdrMFquloroUT/AMjnMhlyjO5TWvlX0oSq5xnYGKP5gBdlOSO8MtqW2rZkN7oip/WX+IQWg3AbraSqVVW6v5V//9k="},329:(A,e,t)=>{t.d(e,{Z:()=>a});const a=t.p+"assets/images/demo-2f7941b1086f75493d0cba4a1d73ffcc.gif"},8926:(A,e,t)=>{t.d(e,{Z:()=>a});const a=t.p+"assets/images/nea-3a1bcf8f2def3c2af15a50c315f2f176.jpg"},5377:(A,e,t)=>{t.d(e,{Z:()=>a});const a="data:image/jpeg;base64,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"}}]); \ No newline at end of file diff --git a/assets/js/runtime~main.15122030.js b/assets/js/runtime~main.772cfd66.js similarity index 65% rename from assets/js/runtime~main.15122030.js rename to assets/js/runtime~main.772cfd66.js index 7d095e18..5ec61eb8 100644 --- a/assets/js/runtime~main.15122030.js +++ b/assets/js/runtime~main.772cfd66.js @@ -1 +1 @@ -(()=>{"use strict";var e,a,f,r,t,c={},d={};function b(e){var a=d[e];if(void 0!==a)return a.exports;var f=d[e]={exports:{}};return c[e].call(f.exports,f,f.exports,b),f.exports}b.m=c,e=[],b.O=(a,f,r,t)=>{if(!f){var c=1/0;for(i=0;i=t)&&Object.keys(b.O).every((e=>b.O[e](f[o])))?f.splice(o--,1):(d=!1,t0&&e[i-1][2]>t;i--)e[i]=e[i-1];e[i]=[f,r,t]},b.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return b.d(a,{a:a}),a},f=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,b.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var t=Object.create(null);b.r(t);var c={};a=a||[null,f({}),f([]),f(f)];for(var d=2&r&&e;"object"==typeof d&&!~a.indexOf(d);d=f(d))Object.getOwnPropertyNames(d).forEach((a=>c[a]=()=>e[a]));return c.default=()=>e,b.d(t,c),t},b.d=(e,a)=>{for(var f in a)b.o(a,f)&&!b.o(e,f)&&Object.defineProperty(e,f,{enumerable:!0,get:a[f]})},b.f={},b.e=e=>Promise.all(Object.keys(b.f).reduce(((a,f)=>(b.f[f](e,a),a)),[])),b.u=e=>"assets/js/"+({53:"935f2afb",110:"66406991",453:"30a24c52",533:"b2b675dd",948:"8717b14a",1018:"c427a252",1372:"1db64337",1477:"b2f554cd",1633:"031793e1",1640:"d0d95016",1713:"a7023ddc",1825:"24990169",1914:"d9f32620",2069:"3fe7e728",2178:"1f6a2402",2216:"f8739703",2267:"59362658",2362:"e273c56f",2535:"814f3328",2594:"04f08d73",2635:"5d0a3898",2808:"39f90b1e",2855:"1fb3fb3e",3085:"1f391b9e",3089:"a6aa9e1f",3205:"a80da1cf",3237:"1df93b7f",3514:"73664a40",3608:"9e4087bc",4013:"01a85c17",4637:"cc5eb3ad",4998:"d2b05863",5049:"74876495",5508:"af45fd03",5792:"04115efe",6103:"ccc49370",6163:"14407088",6519:"1970a410",6603:"29cae6e4",6834:"56604baf",6938:"608ae6a4",7161:"148a37a4",7178:"096bfee4",7414:"393be207",7445:"735d0569",7624:"1359ca2f",7918:"17896441",7973:"f67c2f60",8329:"ebe69912",8426:"5bb8d416",8610:"6875c492",8636:"f4f34a3a",8732:"626d80ff",8828:"06327352",8922:"efcba355",9003:"925b3f96",9035:"4c9e35b1",9514:"1be78505",9642:"7661071f",9700:"e16015ca"}[e]||e)+"."+{53:"187ba7ff",110:"e7915820",453:"0b40efde",533:"408ac344",948:"4b846955",1018:"1c0d8387",1372:"bc01c84c",1477:"beda59e7",1506:"50b230b3",1633:"4d261684",1640:"d6990f68",1713:"f4b99aca",1825:"a1f7da1c",1914:"029d97a2",2069:"05152b39",2178:"91de8530",2216:"182b6c5c",2267:"7ff35a59",2362:"7c3600cf",2529:"a12640b6",2535:"a8f50e33",2594:"31c6c91e",2635:"f2d89e82",2808:"3a7aca4f",2855:"8475655f",3085:"4f0d3eab",3089:"6ae3c350",3205:"dad8b174",3237:"02880ffe",3514:"062e4c31",3608:"019cba0d",4013:"b38f7de3",4637:"c3a5d65e",4972:"30cc58b4",4998:"a48be97b",5049:"7ffb793d",5508:"6c566558",5792:"afc7a094",6103:"7385cc54",6163:"4e7bef33",6519:"d8eae4b9",6603:"90d10c38",6834:"6b8ba181",6938:"50b8b957",7161:"e6ced549",7178:"31110297",7414:"7be5359b",7445:"e72ee2f8",7624:"ef4cd1f0",7918:"c2e76ad7",7973:"b05817ab",8329:"bc5b1b36",8426:"19e980ec",8610:"6b63a7c1",8636:"d978a77e",8732:"9e0db56f",8828:"6cd73b31",8922:"c01b61ca",9003:"18d788dc",9035:"0c238a9c",9514:"df699618",9642:"e79dbec3",9700:"81020c95"}[e]+".js",b.miniCssF=e=>{},b.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),b.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),r={},t="regression-docs:",b.l=(e,a,f,c)=>{if(r[e])r[e].push(a);else{var d,o;if(void 0!==f)for(var n=document.getElementsByTagName("script"),i=0;i{d.onerror=d.onload=null,clearTimeout(l);var t=r[e];if(delete r[e],d.parentNode&&d.parentNode.removeChild(d),t&&t.forEach((e=>e(f))),a)return a(f)},l=setTimeout(s.bind(null,void 0,{type:"timeout",target:d}),12e4);d.onerror=s.bind(null,d.onerror),d.onload=s.bind(null,d.onload),o&&document.head.appendChild(d)}},b.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},b.p="/",b.gca=function(e){return e={14407088:"6163",17896441:"7918",24990169:"1825",59362658:"2267",66406991:"110",74876495:"5049","935f2afb":"53","30a24c52":"453",b2b675dd:"533","8717b14a":"948",c427a252:"1018","1db64337":"1372",b2f554cd:"1477","031793e1":"1633",d0d95016:"1640",a7023ddc:"1713",d9f32620:"1914","3fe7e728":"2069","1f6a2402":"2178",f8739703:"2216",e273c56f:"2362","814f3328":"2535","04f08d73":"2594","5d0a3898":"2635","39f90b1e":"2808","1fb3fb3e":"2855","1f391b9e":"3085",a6aa9e1f:"3089",a80da1cf:"3205","1df93b7f":"3237","73664a40":"3514","9e4087bc":"3608","01a85c17":"4013",cc5eb3ad:"4637",d2b05863:"4998",af45fd03:"5508","04115efe":"5792",ccc49370:"6103","1970a410":"6519","29cae6e4":"6603","56604baf":"6834","608ae6a4":"6938","148a37a4":"7161","096bfee4":"7178","393be207":"7414","735d0569":"7445","1359ca2f":"7624",f67c2f60:"7973",ebe69912:"8329","5bb8d416":"8426","6875c492":"8610",f4f34a3a:"8636","626d80ff":"8732","06327352":"8828",efcba355:"8922","925b3f96":"9003","4c9e35b1":"9035","1be78505":"9514","7661071f":"9642",e16015ca:"9700"}[e]||e,b.p+b.u(e)},(()=>{var e={1303:0,532:0};b.f.j=(a,f)=>{var r=b.o(e,a)?e[a]:void 0;if(0!==r)if(r)f.push(r[2]);else if(/^(1303|532)$/.test(a))e[a]=0;else{var t=new Promise(((f,t)=>r=e[a]=[f,t]));f.push(r[2]=t);var c=b.p+b.u(a),d=new Error;b.l(c,(f=>{if(b.o(e,a)&&(0!==(r=e[a])&&(e[a]=void 0),r)){var t=f&&("load"===f.type?"missing":f.type),c=f&&f.target&&f.target.src;d.message="Loading chunk "+a+" failed.\n("+t+": "+c+")",d.name="ChunkLoadError",d.type=t,d.request=c,r[1](d)}}),"chunk-"+a,a)}},b.O.j=a=>0===e[a];var a=(a,f)=>{var r,t,c=f[0],d=f[1],o=f[2],n=0;if(c.some((a=>0!==e[a]))){for(r in d)b.o(d,r)&&(b.m[r]=d[r]);if(o)var i=o(b)}for(a&&a(f);n{"use strict";var e,f,a,r,t,c={},d={};function b(e){var f=d[e];if(void 0!==f)return f.exports;var a=d[e]={exports:{}};return c[e].call(a.exports,a,a.exports,b),a.exports}b.m=c,e=[],b.O=(f,a,r,t)=>{if(!a){var c=1/0;for(i=0;i=t)&&Object.keys(b.O).every((e=>b.O[e](a[o])))?a.splice(o--,1):(d=!1,t0&&e[i-1][2]>t;i--)e[i]=e[i-1];e[i]=[a,r,t]},b.n=e=>{var f=e&&e.__esModule?()=>e.default:()=>e;return b.d(f,{a:f}),f},a=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,b.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var t=Object.create(null);b.r(t);var c={};f=f||[null,a({}),a([]),a(a)];for(var d=2&r&&e;"object"==typeof d&&!~f.indexOf(d);d=a(d))Object.getOwnPropertyNames(d).forEach((f=>c[f]=()=>e[f]));return c.default=()=>e,b.d(t,c),t},b.d=(e,f)=>{for(var a in f)b.o(f,a)&&!b.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:f[a]})},b.f={},b.e=e=>Promise.all(Object.keys(b.f).reduce(((f,a)=>(b.f[a](e,f),f)),[])),b.u=e=>"assets/js/"+({53:"935f2afb",110:"66406991",453:"30a24c52",533:"b2b675dd",948:"8717b14a",1018:"c427a252",1372:"1db64337",1477:"b2f554cd",1633:"031793e1",1640:"d0d95016",1713:"a7023ddc",1825:"24990169",1914:"d9f32620",2069:"3fe7e728",2178:"1f6a2402",2216:"f8739703",2267:"59362658",2362:"e273c56f",2535:"814f3328",2594:"04f08d73",2635:"5d0a3898",2808:"39f90b1e",2855:"1fb3fb3e",3085:"1f391b9e",3089:"a6aa9e1f",3205:"a80da1cf",3237:"1df93b7f",3514:"73664a40",3608:"9e4087bc",4013:"01a85c17",4637:"cc5eb3ad",4998:"d2b05863",5049:"74876495",5508:"af45fd03",5792:"04115efe",6103:"ccc49370",6163:"14407088",6519:"1970a410",6603:"29cae6e4",6834:"56604baf",6938:"608ae6a4",7161:"148a37a4",7178:"096bfee4",7414:"393be207",7445:"735d0569",7624:"1359ca2f",7918:"17896441",7973:"f67c2f60",8329:"ebe69912",8426:"5bb8d416",8610:"6875c492",8636:"f4f34a3a",8732:"626d80ff",8828:"06327352",8922:"efcba355",9003:"925b3f96",9035:"4c9e35b1",9514:"1be78505",9642:"7661071f",9700:"e16015ca"}[e]||e)+"."+{53:"187ba7ff",110:"e7915820",453:"0b40efde",533:"408ac344",948:"4b846955",1018:"1c0d8387",1372:"bc01c84c",1477:"beda59e7",1506:"50b230b3",1633:"4d261684",1640:"d6990f68",1713:"f4b99aca",1825:"a1f7da1c",1914:"029d97a2",2069:"05152b39",2178:"91de8530",2216:"182b6c5c",2267:"7ff35a59",2362:"7c3600cf",2529:"a12640b6",2535:"a8f50e33",2594:"31c6c91e",2635:"f2d89e82",2808:"3a7aca4f",2855:"8475655f",3085:"4f0d3eab",3089:"6ae3c350",3205:"dad8b174",3237:"8b9d886a",3514:"062e4c31",3608:"019cba0d",4013:"b38f7de3",4637:"c3a5d65e",4972:"30cc58b4",4998:"a48be97b",5049:"7ffb793d",5508:"6c566558",5792:"afc7a094",6103:"7385cc54",6163:"4e7bef33",6519:"d8eae4b9",6603:"90d10c38",6834:"6b8ba181",6938:"50b8b957",7161:"e6ced549",7178:"31110297",7414:"7be5359b",7445:"e72ee2f8",7624:"ef4cd1f0",7918:"c2e76ad7",7973:"b05817ab",8329:"bc5b1b36",8426:"19e980ec",8610:"6b63a7c1",8636:"d978a77e",8732:"9e0db56f",8828:"6cd73b31",8922:"c01b61ca",9003:"18d788dc",9035:"0c238a9c",9514:"df699618",9642:"e79dbec3",9700:"81020c95"}[e]+".js",b.miniCssF=e=>{},b.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),b.o=(e,f)=>Object.prototype.hasOwnProperty.call(e,f),r={},t="regression-docs:",b.l=(e,f,a,c)=>{if(r[e])r[e].push(f);else{var d,o;if(void 0!==a)for(var n=document.getElementsByTagName("script"),i=0;i{d.onerror=d.onload=null,clearTimeout(l);var t=r[e];if(delete r[e],d.parentNode&&d.parentNode.removeChild(d),t&&t.forEach((e=>e(a))),f)return f(a)},l=setTimeout(s.bind(null,void 0,{type:"timeout",target:d}),12e4);d.onerror=s.bind(null,d.onerror),d.onload=s.bind(null,d.onload),o&&document.head.appendChild(d)}},b.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},b.p="/",b.gca=function(e){return e={14407088:"6163",17896441:"7918",24990169:"1825",59362658:"2267",66406991:"110",74876495:"5049","935f2afb":"53","30a24c52":"453",b2b675dd:"533","8717b14a":"948",c427a252:"1018","1db64337":"1372",b2f554cd:"1477","031793e1":"1633",d0d95016:"1640",a7023ddc:"1713",d9f32620:"1914","3fe7e728":"2069","1f6a2402":"2178",f8739703:"2216",e273c56f:"2362","814f3328":"2535","04f08d73":"2594","5d0a3898":"2635","39f90b1e":"2808","1fb3fb3e":"2855","1f391b9e":"3085",a6aa9e1f:"3089",a80da1cf:"3205","1df93b7f":"3237","73664a40":"3514","9e4087bc":"3608","01a85c17":"4013",cc5eb3ad:"4637",d2b05863:"4998",af45fd03:"5508","04115efe":"5792",ccc49370:"6103","1970a410":"6519","29cae6e4":"6603","56604baf":"6834","608ae6a4":"6938","148a37a4":"7161","096bfee4":"7178","393be207":"7414","735d0569":"7445","1359ca2f":"7624",f67c2f60:"7973",ebe69912:"8329","5bb8d416":"8426","6875c492":"8610",f4f34a3a:"8636","626d80ff":"8732","06327352":"8828",efcba355:"8922","925b3f96":"9003","4c9e35b1":"9035","1be78505":"9514","7661071f":"9642",e16015ca:"9700"}[e]||e,b.p+b.u(e)},(()=>{var e={1303:0,532:0};b.f.j=(f,a)=>{var r=b.o(e,f)?e[f]:void 0;if(0!==r)if(r)a.push(r[2]);else if(/^(1303|532)$/.test(f))e[f]=0;else{var t=new Promise(((a,t)=>r=e[f]=[a,t]));a.push(r[2]=t);var c=b.p+b.u(f),d=new Error;b.l(c,(a=>{if(b.o(e,f)&&(0!==(r=e[f])&&(e[f]=void 0),r)){var t=a&&("load"===a.type?"missing":a.type),c=a&&a.target&&a.target.src;d.message="Loading chunk "+f+" failed.\n("+t+": "+c+")",d.name="ChunkLoadError",d.type=t,d.request=c,r[1](d)}}),"chunk-"+f,f)}},b.O.j=f=>0===e[f];var f=(f,a)=>{var r,t,c=a[0],d=a[1],o=a[2],n=0;if(c.some((f=>0!==e[f]))){for(r in d)b.o(d,r)&&(b.m[r]=d[r]);if(o)var i=o(b)}for(f&&f(a);n - + @@ -23,7 +23,7 @@ copy this token and store it in a safe location.

Using the API Key

Once you have generated an API key, you can use it to authenticate against our API. To do so, you must include the key in the Authorization header of your request.

HEADERS
Authorization: Bearer <API_KEY>

Revoking API Keys

You can remove API Keys at any time by deleting them from the account page. Next to each key is a delete icon, which immediately revokes the key.

- + \ No newline at end of file diff --git a/automated-testing/creating-custom-components.html b/automated-testing/creating-custom-components.html index f59b9840..81a377bd 100644 --- a/automated-testing/creating-custom-components.html +++ b/automated-testing/creating-custom-components.html @@ -9,7 +9,7 @@ - + @@ -45,7 +45,7 @@ So there are several ways to add it to your scene. We recommend creating a Prefab and attaching the Bot component to that prefab:

A Unity Prefab showing the &quot;My Bot (Script)&quot; component added

Then, you can add that Prefab to the availableBots property on the RegressionGames UI Overlay, which will add it to the dropdown of bots that can be spwaned in the UI overlay.

A recording showing the user draggin the &quot;MyBot&quot; prefab on to the &quot;Available Bots&quot; list in the &quot;Overlay Menu&quot; section of a game object

- + \ No newline at end of file diff --git a/automated-testing/getting-started.html b/automated-testing/getting-started.html index 46a6a78f..5d8b9d7f 100644 --- a/automated-testing/getting-started.html +++ b/automated-testing/getting-started.html @@ -9,7 +9,7 @@ - + @@ -41,7 +41,7 @@ On the inspector, find the "Automation Recorder" component and click the View Recordings... button. The directory in which the recordings are stored will open in your file explorer.

The Automation Recorder component with the &quot;View Recordings...&quot; button

The macOS Finder showing the directory containing the recordings

Each recording is an .rgrec.zip file. Inside these ZIP files are:

  1. A recording.json file which contains global metadata about the recording (when it was made, who made it, etc.)
  2. A series of snapshot.[frameNumber].json files that contain all the state captured for each frame of the recording. Frames with no state changes are not included in the recording, so if a given frame N is missing, it means that the state of the game did not change between frames N-1 and N.
  3. A series of screenshot.[frameNumber].png files that contain a screenshot of the game for each frame that a screenshot was requested. Bots, and your game code, can use an API on the Automation Controller to request a screenshot at any time. For example, the Monkey Bot requests a screenshot for the frame immediately after it clicks on a UI element.

The macOS Finder showing the contents of a recording

Next steps

From here, you can give the GPT Assistant Bot a try and go beyond random automation!

- + \ No newline at end of file diff --git a/automated-testing/gpt-assistant-bot.html b/automated-testing/gpt-assistant-bot.html index d8658502..577bc115 100644 --- a/automated-testing/gpt-assistant-bot.html +++ b/automated-testing/gpt-assistant-bot.html @@ -9,7 +9,7 @@ - + @@ -38,7 +38,7 @@ If you want to stop the bot, you can click the "Stop Bot" button in the UI Overlay, or simply stop your game.

Writing a good goal

Writing a good goal is important to an effective bot. The GPT Assistant Bot is a very powerful tool, but it's not magic and it takes some work to get good results. Here are some dos and don'ts for writing a good goal:

  • DO reference a very specific end goal. For example "Reach the 'Foo' scene". The Bot knows the name of the active scene and can use that to determine if it has reached the goal.
  • DO reference game objects by name where possible. For example "use the 'IP Start Button' button". The Bot is able to see any Game Object exposed by the Entity Discoverers you have registered in your game as children of the Automation Controller (see the Getting Started Guide for more information on Entity Discoverers).
  • DO try to reference all the steps the bot will need to take, at a high level. The model will see all the interactables in the scene and needs to be able to determine which ones it should interact with. If you have multiple ways of completing a goal, you should specify which one to use.
  • DO write a short goal. The Bot receives a LOT of context information from the game. The longer your Goal is, the more likely you are to hit context limits in the GPT-4 model.
  • DON'T use this bot for highly timing-sensitive goals and gameplay (for example, jumping a gap in a platfomer). There is significant latency between when the bot sees the scene and when a response is returned from OpenAI. This latency is not consistent and can vary from a few seconds to a few minutes. This is a preview and we're working on ways to avoid the impact of this latency in the future (such as allowing the bot to plan ahead for future actions).
  • DON'T expect perfection on the first try. You'll need to refine your goal a little bit to get the results.

Some examples of bad prompts and the "better" prompt we recommend:

Bad: Start a new game on hard.

Good: Reach the 'GameWorld' scene by creating a new character and selecting the 'Hard' difficulty level.

Bad: Chop 10 trees

Good: Select the 'Axe' tool, then chop 10 trees by locating each tree, walking to it, and hitting it until the tree is destroyed.

info

Please join our Discord to get help writing goals, and share your results!

- + \ No newline at end of file diff --git a/automated-testing/overview.html b/automated-testing/overview.html index 8872c2f4..865f7e86 100644 --- a/automated-testing/overview.html +++ b/automated-testing/overview.html @@ -9,14 +9,14 @@ - +

Automated UI Testing for Unity

info

The Automated UI Testing package is currently a preview and we're looking for your feedback! Please submit feedback using our feedback form.

Also, join our Discord to share your creations and get help from the community.

The Regression Games Automated Testing Package for Unity is a set of tools that help you test your game with less code. The package combines several powerful features to help you test your game:

  1. Automatic State Capture and Recording - Regression Games automatically discovers components in your game and allows you to make recordings of their state throughout a gameplay session. These recordings can be analyzed to determine if your game is behaving as expected.

  2. Simple Automation Framework - Regression Games provides a simple framework for automating gameplay, and provides built-in automations for common tasks such as navigating menus.

- + \ No newline at end of file diff --git a/blog.html b/blog.html index 0f91c94a..e6ec2bca 100644 --- a/blog.html +++ b/blog.html @@ -9,13 +9,13 @@ - +

· One min read
Sébastien Lorber
Yangshun Tay

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.

· One min read
Gao Wei

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

- + \ No newline at end of file diff --git a/blog/archive.html b/blog/archive.html index b8eac094..4694d478 100644 --- a/blog/archive.html +++ b/blog/archive.html @@ -9,13 +9,13 @@ - + - + \ No newline at end of file diff --git a/blog/first-blog-post.html b/blog/first-blog-post.html index 67d1c785..f32b39fe 100644 --- a/blog/first-blog-post.html +++ b/blog/first-blog-post.html @@ -9,13 +9,13 @@ - +

First Blog Post

· One min read
Gao Wei

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

- + \ No newline at end of file diff --git a/blog/long-blog-post.html b/blog/long-blog-post.html index 3ec2f195..14a4df47 100644 --- a/blog/long-blog-post.html +++ b/blog/long-blog-post.html @@ -9,13 +9,13 @@ - +

Long Blog Post

· 3 min read
Endilie Yacop Sucipto

This is the summary of a very long blog post,

Use a <!-- truncate --> comment to limit blog post size in the list view.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

- + \ No newline at end of file diff --git a/blog/mdx-blog-post.html b/blog/mdx-blog-post.html index 5df3604e..102adcc2 100644 --- a/blog/mdx-blog-post.html +++ b/blog/mdx-blog-post.html @@ -9,13 +9,13 @@ - +

MDX Blog Post

· One min read
Sébastien Lorber

Blog posts support Docusaurus Markdown features, such as MDX.

tip

Use the power of React to create interactive blog posts.

<button onClick={() => alert('button clicked!')}>Click me!</button>
- + \ No newline at end of file diff --git a/blog/tags.html b/blog/tags.html index f196ac38..8d0c87ba 100644 --- a/blog/tags.html +++ b/blog/tags.html @@ -9,13 +9,13 @@ - + - + \ No newline at end of file diff --git a/blog/tags/docusaurus.html b/blog/tags/docusaurus.html index 0acdcce4..235af6c6 100644 --- a/blog/tags/docusaurus.html +++ b/blog/tags/docusaurus.html @@ -9,13 +9,13 @@ - +

4 posts tagged with "docusaurus"

View All Tags

· One min read
Sébastien Lorber
Yangshun Tay

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.

· One min read
Gao Wei

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

- + \ No newline at end of file diff --git a/blog/tags/facebook.html b/blog/tags/facebook.html index 8e16684d..631005e3 100644 --- a/blog/tags/facebook.html +++ b/blog/tags/facebook.html @@ -9,13 +9,13 @@ - +

One post tagged with "facebook"

View All Tags

· One min read
Sébastien Lorber
Yangshun Tay

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.

- + \ No newline at end of file diff --git a/blog/tags/hello.html b/blog/tags/hello.html index 0fd84bfd..7f02a4b6 100644 --- a/blog/tags/hello.html +++ b/blog/tags/hello.html @@ -9,13 +9,13 @@ - +

2 posts tagged with "hello"

View All Tags

· One min read
Sébastien Lorber
Yangshun Tay

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.

- + \ No newline at end of file diff --git a/blog/tags/hola.html b/blog/tags/hola.html index cc4588b3..37e66241 100644 --- a/blog/tags/hola.html +++ b/blog/tags/hola.html @@ -9,13 +9,13 @@ - +

One post tagged with "hola"

View All Tags

· One min read
Gao Wei

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. Lorem ipsum dolor sit amet

- + \ No newline at end of file diff --git a/blog/welcome.html b/blog/welcome.html index 1aa79271..ffba0424 100644 --- a/blog/welcome.html +++ b/blog/welcome.html @@ -9,13 +9,13 @@ - +

Welcome

· One min read
Sébastien Lorber
Yangshun Tay

Docusaurus blogging features are powered by the blog plugin.

Simply add Markdown files (or folders) to the blog directory.

Regular blog authors can be added to authors.yml.

The blog post date can be extracted from filenames, such as:

  • 2019-05-30-welcome.md
  • 2019-05-30-welcome/index.md

A blog post folder can be convenient to co-locate blog post images:

Docusaurus Plushie

The blog supports tags as well!

And if you don't want a blog: just delete this directory, and use blog: false in your Docusaurus config.

- + \ No newline at end of file diff --git a/changelog.html b/changelog.html index 9105d382..d5da18be 100644 --- a/changelog.html +++ b/changelog.html @@ -9,7 +9,7 @@ - + @@ -22,7 +22,7 @@ in GitHub Actions (and other CI/CD systems via GameCI)
  • UI improvements to Behavior Tree Beta
  • Updated defaults for RG Unity SDK to be more user-friendly
  • The RG Unity SDK now includes its own font assets for better interoperability
  • Links to download Zip bots from dashboard are now available
  • Bug fixes

    • Fixed issue where the website would freeze in some match loading scenarios
    • Fixed broken links in documentation
    • Fixed issue where Agent Builder code generation would flicker
    • Fixed bug where Unity actions would sometimes be sent to the wrong bots
    • Fixed bug where instant bots would not start when the user did not have a linked GitHub account

    Security fixes

    • Fixed bug where lobby APIs would reveal email addresses

    Coming Soon

    • Continued improvements and additions to the Unity attribute system
    • Additional samples and guides for various use cases
    • New features for the Agent Builder tool

    Release 0.0.11

    August 28, 2023

    info

    This version is a release preview. Our product is in beta and we would love for developers to try it out and provide feedback! Contact us at info@regression.gg for dedicated support and access.

    New Platform Features

    • Agent Builder Beta - Our GPT-enabled agent builder product is live for select players, now with improved validation tools. If you'd like to try it out, let us know!
    • Our documentation site is now live! This docs site includes API/SDK references, tutorials, guides, and FAQs for both players and developers.
    • API Keys - developers and players can now create API keys to interact with RG services
    • New onboarding flow for players and game developers
    • The ID of a bot can now be seen and copied within the Bot Manager
    • Zip Bots - Bots uploaded via zip can now be downloaded
    • The home page has been redesigned to provide players more information about getting started.

    Unity SDK Features

    • An early preview of our Unity SDK for building AI agents is now live! Our docs site has a getting started guide - message us for access.
    • Developers can now create Unity bots from the Bot Manager
    • Logs for bots can now be downloaded - available via API or through the Bot History dashboard
    • Character configuration for Unity bots is more flexible and customizable
    • Validation results for QA testing bots are now saved to Unity Replay files, allowing for viewing the validation directly within Unity
    • Default settings for the SDK have been adjusted for increased ease of use
    • Added a “Stop All” button for stopping bots from within the Unity game

    Bug Fixes

    • Fixed issue where choosing a bot repository via commit would throw an error
    • Fixed a bug where bot logs would not show the correct number of lines before clearing
    • Fixed issues where Unity bots would not teardown properly
    • Fixed a bug where login and registration would sometimes fail
    • Feedback button has been moved to a better spot on the screen to avoid hiding other components
    • Fixed issue with SSL certs on certain systems

    Migration Notes

    • For Unity developers: the namespace for various classes in the Unity SDK have been updated. Please make sure to add the following import declaration in your files that use classes from Regression Games.
    using RegressionGames;

    Coming Soon

    • New attribute-based system for Unity SDK integration. New attributes will permit defining bot actions and state from existing functions and variables within your code.
    • CI/CD support - Instructions and examples will be added for running a Quality Assurance Bots in GitHub Actions.
    - + \ No newline at end of file diff --git a/creating-bots/csharp/adaptive-bots.html b/creating-bots/csharp/adaptive-bots.html index f79ab9e9..b9458bb2 100644 --- a/creating-bots/csharp/adaptive-bots.html +++ b/creating-bots/csharp/adaptive-bots.html @@ -9,7 +9,7 @@ - + @@ -22,7 +22,7 @@ API methods that filter state objects and check conditions will record additional decision results. These are displayed side-by-side with Bot actions in the Replay utility to help debug your Bot by showing which decisons led to resulting behaviors.

    info

    If you are using the [RGAction] attribute to generate your actions, then there are also typed RGActionRequest classes generated for that action. The snippets below provide examples for using both typed and untyped actions.

    caution

    Commands within ProcessTick interact with the game state represented by the current tick only. This contrasts with Scenario Bots, which can delay execution of commands for several ticks until expected conditions are met.

    public override void ConfigureBot(RG rgObject)
    {
    rgObject.CharacterConfig = new Dictionary<string, object>() {
    { "role", "Warrior" }
    };
    }

    /**
    * Outline of our Bot algorithm. For every tick:
    * - If the Bot is standing on a switch that is holding a door open, then do nothing
    * - If the switch is within a range of sqrt(30) units from the Bot, move onto the switch
    * - If the Bot is not near the player, move within range of the player
    * - If an enemy is within a certain distance of a player, attack that enemy
    */
    public override void ProcessTick(RG rgObject)
    {

    if (rgObject.SceneName != "Dungeon")
    {
    return;
    }

    var currentPosition = (Vector3)rgObject.GetMyPlayers()[0].position;

    var floorSwitch = rgObject.FindEntities("FloorSwitch");
    if (floorSwitch.Count > 0 && rgObject.EntityHasAttribute(floorSwitch[0], "isOn", true))
    {
    return;
    }

    if (floorSwitch.Count > 0 && MathFunctions.DistanceSq(currentPosition, (Vector3)floorSwitch[0].position) < 30)
    {
    return;
    }

    var humanPlayer = rgObject.FindEntities("HumanPlayer");
    if (humanPlayer.Count > 0 &&
    MathFunctions.DistanceSq(currentPosition, (Vector3)humanPlayer[0].position) > 10)
    {
    // Untyped action request
    rgObject.PerformAction(new RGActionRequest("ApproachObject", new Dictionary<string, object>()
    {
    { "targetId", humanPlayer[0].id },
    { "range", 2}
    }));
    }

    var enemy = rgObject.FindNearestEntity(null, currentPosition,
    (entity) => 1.Equals(entity.GetField("team")) && !true.Equals(entity.GetField("broken")));
    if (enemy != null && 0.CompareTo(enemy.GetField("Health")) < 0)
    {
    /*
    * Typed action request
    *
    * Using Generated Class ...
    public class RGActionRequest_PerformSkill : RGActionRequest
    {
    public RGActionRequest_PerformSkill(int skillId, int targetId, Vector3 position)
    {
    action = "PerformSkill";
    Input = new ()
    {{"skillId", skillId}, {"targetId", targetId}, {"position", position}, };
    }
    }
    *
    */
    rgObject.PerformAction(new RGActionRequest_PerformSkill(1, enemy.id, enemy.position));
    }
    }
    - + \ No newline at end of file diff --git a/creating-bots/csharp/configuration.html b/creating-bots/csharp/configuration.html index 2e20a1dc..7a67dfa9 100644 --- a/creating-bots/csharp/configuration.html +++ b/creating-bots/csharp/configuration.html @@ -9,7 +9,7 @@ - + @@ -30,7 +30,7 @@ A MANAGED Bot will automatically disconnect when RGBotServerListener.GetInstance()?.StopGame() is called from the Unity Integration. A PERSISTENT Bot must either terminate itself (see complete()) when its tasks are complete or be terminated manually from the RG Overlay. This allows PERSISTENT bots to stay active across multiple scenes/sessions.

    Examples

    protected override RGBotLifecycle GetBotLifecycle()
    {
    return RGBotLifecycle.MANAGED;
    }
    - + \ No newline at end of file diff --git a/creating-bots/csharp/scenario-testing.html b/creating-bots/csharp/scenario-testing.html index af54e924..6b8778b2 100644 --- a/creating-bots/csharp/scenario-testing.html +++ b/creating-bots/csharp/scenario-testing.html @@ -9,13 +9,13 @@ - + - + \ No newline at end of file diff --git a/creating-bots/csharp/utilities.html b/creating-bots/csharp/utilities.html index de7be042..87c63b8e 100644 --- a/creating-bots/csharp/utilities.html +++ b/creating-bots/csharp/utilities.html @@ -9,7 +9,7 @@ - + @@ -32,7 +32,7 @@ if you create them and then turn off Gizmos. If you want to remove them, you must call DestroyAllTexts().

    Putting it all together

    Let's put this all together! Here is a snippet of code from the a bot written for Unity's Kart Racer sample. This demonstrates creating lines, spheres, text, and removing some of these elements.

    // Inside of processTick()

    counter++; // We keep a counter so we can keep track of the gizmos we draw
    var thisAgent = rgObject.FindPlayers()[0];
    var nextWaypoint = ...; // We grab the RGStateEntity for the next waypoint our racer should follow
    var distance = ...; // Calculate some parameters we want to debug and show

    RGGizmos.CreateLine(thisAgent.id, nextWaypoint.position, Color.green, "Next Waypoint Line" + counter);
    RGGizmos.CreateSphere(nextWaypoint.position, Color.red, 0.3f, true, "Next Waypoint Spot" + counter);
    RGGizmos.CreateText(thisAgent.id, $"Distance: {distance}");

    // Only keep the four latest lines and spheres
    if (counter > 4)
    {
    RGGizmos.DestroyLine("Next Waypoint Line" + (counter - 4));
    RGGizmos.DestroySphere("Next Waypoint Spot" + (counter - 4));
    }
    - + \ No newline at end of file diff --git a/creating-bots/javascript/adaptive-bots.html b/creating-bots/javascript/adaptive-bots.html index a2fb8779..29b98235 100644 --- a/creating-bots/javascript/adaptive-bots.html +++ b/creating-bots/javascript/adaptive-bots.html @@ -9,7 +9,7 @@ - + @@ -37,7 +37,7 @@ If this is an Object Type, this method will return true if any entities with this ObjectType exist.

    Arguments

    Argument NameTypeDefaultDescription
    entityobject | number | stringThe entity, its id, or an Object Type. If this is an Object Type, will return true if any entities with this ObjectType exist.

    Return Value

    Promise<boolean>

    Examples

    const entity = await rg.findEntity("Williward");
    ...
    const exists = await rg.entityExists(entity);

    entityDoesNotExist(entity: object | number | string);

    Return whether the given entity does not exist. The entity argument can be a reference to an entity, its id, or an Object Type. If this is an Object Type, this method will return true if no entities with this ObjectType exist.

    Arguments

    Argument NameTypeDefaultDescription
    entityobject | number | stringThe entity, its id, or an Object Type. If this is an Object Type, will return true if no entities with this ObjectType exist.

    Return Value

    Promise<boolean>

    Examples

    const staleEntity = await rg.findEntity("Williward");
    ...
    const exists = await rg.entityDoesNotExist(staleEntity);

    entityHasAttribute(targetEntity: object, stateAttribute: string | string[], expectedValue: any);

    Return whether the entity in the game state has the expected value for one of its attributes.

    Arguments

    Argument NameTypeDefaultDescription
    targetEntityobjectThe entity
    stateAttributestring | string[]The name of the attribute key, or an array of keys for nested attributes
    expectedValueanyThe expected value for the entity's state attribute

    Return Value

    Promise<boolean>

    Examples

    const entity = await rg.findEntity("Williward");
    if(await rg.entityHasAttribute(entity, "color", "teal")) {
    console.log("Williward is looking good!")
    }
    - + \ No newline at end of file diff --git a/creating-bots/javascript/agent-builder.html b/creating-bots/javascript/agent-builder.html index 4ccf23b8..d82b8699 100644 --- a/creating-bots/javascript/agent-builder.html +++ b/creating-bots/javascript/agent-builder.html @@ -9,7 +9,7 @@ - + @@ -74,7 +74,7 @@ You may need to alter your prompt and re-submit it for new output when this happens, or you can fix the output manually.

    Validating Code

    The embedded code editor offers standard syntax highlighting and intelligent code completion features for Regressions Games APIs. To take this a step further, our AI code assistant can analyze code from the editor and provide suggestions for fixing syntax errors, bugs, and inefficiencies. Clicking the "Validate Code" button will cause a text box to appear with the assistant's analysis results.

    Let's give this a try with some code that doesn't properly await one of our async APIs.

    class LeafNode extends TreeNode {
    public override async execute(rg): Promise<NodeStatus> {
    const bot = rg.getBot();
    const nearestEnemy = rg.findNearestEntity("Enemy", bot.position);
    this.setData("enemy", nearestEnemy);
    return nearestEnemy ? NodeStatus.SUCCESS : NodeStatus.FAILURE;
    }
    }

    Clicking the "Validate Code" button should result in a warning that findNearestEntity should be awaited if we want to capture the actual "Enemy" entity.

    Validate Code

    You can close validation results at any time and reopen them by clicking the clipboard icon.

    ReOpen Validation Results

    Saving Your Tree

    Save your tree early and often! Any changes made to your AI will be lost if you leave the Agent Builder without saving.

    Save Your Tree

    - + \ No newline at end of file diff --git a/creating-bots/javascript/configuration.html b/creating-bots/javascript/configuration.html index 6b095859..ff305d2d 100644 --- a/creating-bots/javascript/configuration.html +++ b/creating-bots/javascript/configuration.html @@ -9,7 +9,7 @@ - + @@ -33,7 +33,7 @@ A MANAGED Bot will automatically disconnect when RGBotServerListener.GetInstance()?.StopGame() is called from the Unity Integration. A PERSISTENT Bot must either terminate itself (see complete()) when its tasks are complete or be terminated manually from the RG Overlay. This allows PERSISTENT bots to stay active across multiple scenes/sessions.

    Type

    string

    Default Value

    "MANAGED"

    Examples

    export function configureBot(rg) {
    rg.lifecycle = "MANAGED";
    }
    - + \ No newline at end of file diff --git a/creating-bots/javascript/scenario-testing.html b/creating-bots/javascript/scenario-testing.html index cbcf800c..0a9e67d2 100644 --- a/creating-bots/javascript/scenario-testing.html +++ b/creating-bots/javascript/scenario-testing.html @@ -9,7 +9,7 @@ - + @@ -24,7 +24,7 @@ and where the game state must meet the explicit expectations of one command before the next command is executed or else the scenario will fail.

    caution

    This mode should not be used for Bots intended to make dynamic decisions based on the current game state, where a falsey result from a command should not cause the scenario to fail.

    export function configureBot(rg) {
    rg.lifecycle = "PERSISTENT";
    rg.characterConfig = {
    role: "HEALER"
    };
    }

    export async function startScenario(rg) {

    // validate that we're in the game
    await rg.waitForScene("Dungeon");

    // find the closest human player and use a healing ability on them
    let target = await rg.findNearestEntity("HumanPlayer");
    await rg.entityExists(target);

    rg.performAction("Heal", {
    targetId: target.id,
    position: target.position
    })

    // validate that the healing ability recovers from cool-down
    await rg.entityHasAttribute(rg.getBot(), ["abilityAvailable", "Heal"], true);

    // find the closest enemy and use a basic attack until it dies.
    // measure from the position of a known gameObject
    target = await rg.findNearestEntity("Imp", await findEntity("Checkpoint").position);
    await rg.entityExists(target);
    await rg.entityHasAttribute(target, "health", 15);

    // approach the entity
    rg.performAction("ApproachObject", {
    targetId: target.id,
    range: 5,
    });

    // queue three attacks
    // each one should do 5 damage
    const args = {
    targetId: target.id,
    xPosition: target.position,
    }
    rg.performAction("BasicAttack", args)
    await rg.entityHasAttribute(target, "health", 10);

    rg.performAction("BasicAttack", args)
    await rg.entityHasAttribute(target, "health", 5);

    rg.performAction("BasicAttack", args)
    await rg.entityDoesNotExist(target);

    rg.complete();
    }

    Methods

    These methods are in addition to the APIs defined in the Adaptive Bots section.

    recordValidation(validationName: string, result: "PASS" | "FAIL" | "WARNING", options);

    Records a validation result that can later be seen in the Validations Dashboard.

    Arguments

    Argument NameTypeDefaultDescription
    validationNamestringThe name or message of the test to show in the UI
    result"PASS" | "FAIL" | "WARNING"The result of the test
    optionsobject{}Additional options for the validation
    options.icon"clock" | "heart" | "key" | "sparkles"The icon to show next to this validation in the Validations Dashboard

    Return Value

    None

    Examples

    rg.recordValidation("The character has a cooldown after using an ability", "PASS", {icon: "key"})
    rg.recordValidation("The character does not get stuck in the same spot for more than 30 seconds", "FAIL", {icon: "clock"})
    rg.recordValidation("The character cannot move while attacking", "WARNING", {icon: "heart"})

    setCommandTimeout(timeout: number);

    Sets the total time in milliseconds a command is allowed to sped waiting/retrying before it fails. This timeout should take into consideration how often your Unity Integration is configured to send the game state.

    Arguments

    Argument NameTypeDefaultDescription
    timeoutnumberThe new command timeout in milliseconds

    Return Value

    No return value

    Examples

    rg.setCommandTimeout(5000);

    setCommandRetryRate(retryRate: number);

    Sets how long in milliseconds a command should wait before retrying following a failure.

    Arguments

    Argument NameTypeDefaultDescription
    retryRatenumberThe new command retry rate in milliseconds

    Return Value

    No return value

    Examples

    rg.setCommandRetryRate(200);

    waitForScene(sceneName: string);

    Wait until the current scene name matches the expected value.

    Arguments

    Argument NameTypeDefaultDescription
    sceneNamestringThe name of the scene to wait for

    Return Value

    Promise<void>

    Examples

    await rg.waitForScene("StartupScreen");
    await rg.waitForScene("UpdaterSplash");
    await rg.waitForScene("MainMenu")
    - + \ No newline at end of file diff --git a/index.html b/index.html index 25c095f5..bcefe00a 100644 --- a/index.html +++ b/index.html @@ -9,13 +9,13 @@ - +
    -

    Improve quality and reduce costs with AI agents

    Regression Games helps game developers go from zero to one with AI agent development

    Regression Games
    Demo of bots validating abilities in Boss Room (created by Unity), the timeline feature, and the automated Agent Builder.

    A Plethora of Features

    Regression Games is building the best platform for AI agent development with replay features, validation libraries, CI/CD integration, and more.

    Ease of Integration

    Whether you are building an MMORPG or a simple 2D platformer, the Regression Games SDK follows a simple integration pattern to get you up and running quickly.

    Bot Versatility

    Bots on Regression Games can click through menus, control spawned characters, play test with humans, validate behaviors, and more.

    BACKED BY TIER 1 INVESTORS
    - +

    Improve quality and reduce costs with AI agents

    Regression Games helps game developers go from zero to one with AI agent development

    Get started immediately by adding the package to Unity:
    https://github.com/Regression-Games/RGUnityBots.git?path=src/gg.regression.unity.bots#v0.0.16
    Regression Games
    Demo of bots validating abilities in Boss Room (created by Unity), the timeline feature, and the automated Agent Builder.

    A Plethora of Features

    Regression Games is building the best platform for AI agent development with replay features, validation libraries, CI/CD integration, and more.

    Ease of Integration

    Whether you are building an MMORPG or a simple 2D platformer, the Regression Games SDK follows a simple integration pattern to get you up and running quickly.

    Bot Versatility

    Bots on Regression Games can click through menus, control spawned characters, play test with humans, validate behaviors, and more.

    BACKED BY TIER 1 INVESTORS
    + \ No newline at end of file diff --git a/integrating-with-unity/BotInformation.html b/integrating-with-unity/BotInformation.html index a9e78e4f..3a747253 100644 --- a/integrating-with-unity/BotInformation.html +++ b/integrating-with-unity/BotInformation.html @@ -9,7 +9,7 @@ - + @@ -19,7 +19,7 @@ passed into the generic of this function. This characterConfig is the raw object that comes from the bot logic.

    Arguments

    None

    Return Value

    The object of type T that has been deserialized from JSON in the characterConfig field.

    Examples

    [Serializable]
    public class BotCharacterConfig
    {
    public float speed;
    }

    var myBotConfig = botInformation.ParseCharacterConfig<BotCharacterConfig>();
    Debug.Log(myBotConfig.speed);

    public void UpdateCharacterConfig<T>(T newConfig)

    Overrides the characterConfig (C#) (JavaScript) defined in the JavaScript code for your bot. For example, when seating a bot, you may discover that the requested character type is no longer available, and you need to let the bot know. The generic type you pass in must be [Serializable].

    Arguments

    Argument NameTypeDefaultDescription
    lateJoinboolrequiredIf true, this bot is joining after the game started or after any initial bots have been spawned

    Return Value

    None

    Examples

    [Serializable]
    public class BotCharacterConfig
    {
    public float speed;
    }
    var newConfig = BotCharacterConfig()
    newConfig.speed = 1000;
    var myBotConfig = botInformation.UpdateCharacterConfig<BotCharacterConfig>(newConfig);
    - + \ No newline at end of file diff --git a/integrating-with-unity/defining-actions.html b/integrating-with-unity/defining-actions.html index c6d1213f..f436f46c 100644 --- a/integrating-with-unity/defining-actions.html +++ b/integrating-with-unity/defining-actions.html @@ -9,7 +9,7 @@ - + @@ -24,7 +24,7 @@ If your Javascript bot needs to call a method with non-primitive parameters, consider using a proxy method:

    // Proxy method for the AttackPlayer action
    [RGAction]
    public void AttackPlayerProxy(int playerId)
    {
    var playerGameObject = RGFindUtils.Instance.FindOneByInstanceId(playerId);
    AttackPlayer(playerGameObject);
    }

    // The method we want to expose as an action
    private void AttackPlayer(GameObject player)
    {
    // your implementation here...
    }

    Invoking an RGAction on a GameObject

    As mentioned above, using the [RGAction] attribute causes Regression Games to generate a new code class for handling invoking actions for that MonoBehaviour.

    One of the generated classes is an RGActionRequest which can be used by your bot code to quickly invoke an action on a specific game object.

    info

    Note that by default you can only invoke actions on GameObjects for bots owned by your client id, or on global action handlers registered on the Regression Games overlay.

    Clicking UI buttons is a global action handler available by default on the overlay. Clicking a button is included in the example below.

    [RGAction] Code Generation Example

    Source File: Player.cs

    public class Player : MonoBehaviour
    {
    public float speed = 100f;
    public float range = 1f;
    private RigidBody _rigidbody;
    private Vector3? _targetPosition;

    void Start()
    {
    _rigidbody = GetComponent<Rigidbody>();
    }

    public void Update()
    {
    // If we are in range, reset the action
    if (targetPosition != null && Vector3.Distance((Vector3) targetPosition, transform.position) < range)
    {
    targetPosition = null;
    }

    // Set the target velocity
    if (targetPosition != null)
    {
    Vector3 direction = ((Vector3)targetPosition - transform.position).normalized;
    direction.y = 0;
    float force = speed * Time.deltaTime;
    _rigidbody.AddForce(direction * force);
    }
    }

    [RGAction]
    public void MoveToPosition(float x, float y, float z)
    {
    targetPosition = new Vector3(x, y, z);
    }
    }

    Generated File: Generated_RGActions_Player.cs

        public class RGActions_Player : IRGActions
    {
    public static readonly Type BehaviourType = typeof(Player);
    public static readonly string EntityTypeName = "Player";
    public static readonly IDictionary<string, Delegate> ActionRequestDelegates = new ReadOnlyDictionary<string, Delegate>(new Dictionary<string, Delegate>()
    {
    {RGActionRequest_Player_MoveToPosition.ActionName, new Action<GameObject, RGActionRequest>(RGAction_Player_MoveToPosition.InvokeOnGameObject)}
    });
    }

    public class RGActionRequest_Player_MoveToPosition : RGActionRequest
    {
    public RGActionRequest_Player_MoveToPosition(float x, float y, float z): base("MoveToPosition")
    {
    Input["x"] = x;
    Input["y"] = y;
    Input["z"] = z;
    }

    public static readonly string EntityTypeName = "Player";
    public static readonly string ActionName = "MoveToPosition";
    public float x => (float)Input!["x"];
    public float y => (float)Input!["y"];
    public float z => (float)Input!["z"];
    }

    public class RGAction_Player_MoveToPosition : IRGAction
    {
    public static void InvokeOnGameObject(GameObject gameObject, RGActionRequest actionRequest)
    {
    // optimize this for local C# bots to avoid all the conversions/etc
    if (actionRequest is RGActionRequest_Player_MoveToPosition myActionRequest)
    {
    InvokeOnGameObject(gameObject, myActionRequest.x, myActionRequest.y, myActionRequest.z);
    }
    else
    {
    InvokeOnGameObject(gameObject, actionRequest.Input);
    }
    }

    private static void InvokeOnGameObject(GameObject gameObject, Dictionary<string, object> input)
    {
    float x = default;
    if (input.TryGetValue("x", out var xInput))
    {
    try
    {
    float.TryParse(xInput.ToString(), out x);
    }
    catch (Exception ex)
    {
    RGDebug.LogError($"Failed to parse 'x' - {ex}");
    }
    }
    else
    {
    RGDebug.LogError("No parameter 'x' found");
    return;
    }

    float y = default;
    if (input.TryGetValue("y", out var yInput))
    {
    try
    {
    float.TryParse(yInput.ToString(), out y);
    }
    catch (Exception ex)
    {
    RGDebug.LogError($"Failed to parse 'y' - {ex}");
    }
    }
    else
    {
    RGDebug.LogError("No parameter 'y' found");
    return;
    }

    float z = default;
    if (input.TryGetValue("z", out var zInput))
    {
    try
    {
    float.TryParse(zInput.ToString(), out z);
    }
    catch (Exception ex)
    {
    RGDebug.LogError($"Failed to parse 'z' - {ex}");
    }
    }
    else
    {
    RGDebug.LogError("No parameter 'z' found");
    return;
    }

    InvokeOnGameObject(gameObject, x, y, z);
    }

    private static void InvokeOnGameObject(GameObject gameObject, params object[] args)
    {
    var monoBehaviour = gameObject.GetComponent<Player>();
    if (monoBehaviour == null)
    {
    //TODO (REG-1420): It would be nice if we could link them to the exact game object in the scene quickly.
    RGDebug.LogError($"Error: Regression Games internal error... Somehow RGAction: MoveToPosition got registered on a GameObject where MonoBehaviour: Player does not exist.");
    return;
    }

    monoBehaviour.MoveToPosition((float)args[0], (float)args[1], (float)args[2]);
    }
    }

    Invoking Actions from Bot code

    To invoke the RGActionRequest_Player_MoveToPosition from your bot, your bot code would look something like this.

        public class BotEntryPoint : RGUserBot
    {
    protected override bool GetIsSpawnable()
    {
    return false;
    }

    protected override RGBotLifecycle GetBotLifecycle()
    {
    return RGBotLifecycle.PERSISTENT;
    }

    public override void ConfigureBot(RG rgObject)
    {
    rgObject.CharacterConfig = new Dictionary<string, object>() {
    { "characterType", "Mage" }
    };
    }

    public override void ProcessTick(RG rgObject)
    {
    switch (rgObject.SceneName)
    {
    case "CharSelect":
    var readyButton = rgObject.GetInteractableButtonByScenePath("/CharacterSelectCanvas/ClassInfoBox/DecorativeFrame/Ready Btn");
    if (readyButton != null)
    {
    rgObject.PerformAction(new RGActionRequest_ClickButton(readyButton.id));
    }
    break;
    case "BossRoom":
    try
    {
    var entities = rgObject.AllEntities();
    if (entities.Count > 0)
    {
    var target = entities[new Random().Next(entities.Count)];
    var targetPosition = target.position;
    var action = new RGActionRequest_Player_MoveToPosition(
    targetPosition.x,
    targetPosition.y,
    targetPosition.z
    );
    rgObject.PerformAction(action);
    }
    else
    {
    RGDebug.LogWarning("No entities found...");
    }
    }
    catch (Exception ex)
    {
    RGDebug.LogError($"Error getting target position: {ex}");
    }

    break;
    case "PostGame":
    default:
    // teardown myself
    rgObject.Complete();
    break;
    }
    }

    }
    - + \ No newline at end of file diff --git a/integrating-with-unity/defining-states.html b/integrating-with-unity/defining-states.html index 58c9dc47..b2161cb7 100644 --- a/integrating-with-unity/defining-states.html +++ b/integrating-with-unity/defining-states.html @@ -9,7 +9,7 @@ - + @@ -28,7 +28,7 @@ Only fields, properties, or methods with this attribute specified will be included in the state.

    [RGState] Example 1

    This example shows using [RGState] without using [RGStateType]. This example also overrides the name of the CharacterType property to charType.

    Source File: WandererState.cs

    public class WandererState : MonoBehaviour
    {
    [RGState("charType")]
    public string CharacterType()
    {
    return "Wanderer";
    }

    public int Health()
    {
    return 50;
    }
    }

    Generated File: RGStateEntity_WandererState.Generated.cs

    public class RGStateEntity_WandererState : RGStateEntityBase
    {
    public static readonly Type BehaviourType = typeof(WandererState);
    public static readonly string EntityTypeName = "WandererState";
    public static readonly bool IsPlayer = false;

    public override string GetEntityType()
    {
    return EntityTypeName;
    }

    public override bool GetIsPlayer()
    {
    return IsPlayer;
    }

    public override void PopulateFromMonoBehaviour(MonoBehaviour monoBehaviour)
    {
    var behaviour = (WandererState)monoBehaviour;
    this["charType"] = behaviour.CharacterType();
    }

    public string charType => (string)this["charType"];
    }

    Note that the Health property is NOT included because it does not have an [RGState] attribute.

    In addition to the core state properties, this GameObject will also have a property in the state for this generated class.

    NameTypeDescription
    WandererStateRGStateEntity_WandererStateThe properties of the WandererState MonoBehaviour on this GameObject.

    How to access this state from bot code...

    public override void ProcessTick(RG rgObject)
    {
    // find a my player which has `WandererState`
    var player = rgObject.GetMyPlayer();
    if (player == null)
    {
    return;
    }

    // Using non-typed lookups (These do NOT require `using`s specific to your generated code)
    var nonTypedAccessOfState = player.GetField("WandererState") as IRGStateEntity;
    var nonTypedCharTypeLookup = nonTypedAccessOfState?.GetField<string>("charType");

    // OR... Using typed lookups (These DO require `using`s specific to your generated code)
    var typedAccessOfState = player.GetFields<RGStateEntity_WandererState>().FirstOrDefault();
    var typedCharTypeLookup = typedAccessOfState?.charType;
    }

    [RGState] Example 2

    This example shows using [RGState] while also using [RGStateType].

    Source File: NomadState.cs

    [RGStateType("nomad")]
    public class NomadState : MonoBehaviour
    {
    public string CharacterType()
    {
    return "Nomad";
    }

    [RGState]
    public int Health()
    {
    return 50;
    }
    }

    Generated File: RGStateEntity_NomadState.Generated.cs

    public class RGStateEntity_NomadState : RGStateEntityBase
    {
    public static readonly Type BehaviourType = typeof(NomadState);
    public static readonly string EntityTypeName = "nomad";
    public static readonly bool IsPlayer = false;

    public override string GetEntityType()
    {
    return EntityTypeName;
    }

    public override bool GetIsPlayer()
    {
    return IsPlayer;
    }

    public override void PopulateFromMonoBehaviour(MonoBehaviour monoBehaviour)
    {
    var behaviour = (NomadState)monoBehaviour;
    this["Health"] = behaviour.Health();
    }

    public string Health => (string)this["Health"];
    }

    Note that the CharacterType property is NOT included because it does not have an [RGState] attribute.

    In addition to the core state properties, this GameObject will also have a property in the state for this generated class.

    NameTypeDescription
    nomadRGStateEntity_NomadStateThe properties of the NomadState MonoBehaviour on this GameObject.

    How to access this state from bot code...

    public override void ProcessTick(RG rgObject)
    {
    // find a my player which has `nomad`
    var player = rgObject.GetMyPlayer();
    if (player == null)
    {
    return;
    }

    // Using non-typed lookups (These do NOT require `using`s specific to your generated code)
    var nonTypedAccessOfState = player.GetField("nomad") as IRGStateEntity;
    var nonTypedHealthLookup = nonTypedAccessOfState?.GetField<int>("Health");

    // OR... Using typed lookups (These DO require `using`s specific to your generated code)
    var typedAccessOfState = player.GetFields<RGStateEntity_NomadState>().FirstOrDefault();
    var typedHealthLookup = typedAccessOfState?.Health;
    }

    4 - RGActionBehaviour MonoBehaviour

    By adding a Behaviour that extends RGActionBehaviour to a GameObject, that GameObject will be included in the state. Unless one of the other methods is also used, this will include only the core state properties of the GameObject and a property with the name of class extending RGActionBehaviour. The value of the property will be RGStateEntity_Empty which has no field accessors.

    info

    RGActionBehaviour is an abstract class allowing for fully custom bot action implementations.

    It is currently available and used internally for handling button click actions, but is still under development and may be subject to change or breakage going forward.

    See Defining Actions for more information about defining actions.

    5 - [RGAction] Attribute

    By adding the [RGAction] attribute to any method in a MonoBehaviour class in your project, ALL GameObjects with that MonoBehaviour attached will be included in the state.

    Any MonoBehaviour using this attribute will be included in the state under a property named the same as the Behaviour's class name or the typeName specified in its [RGStateType] attribute if it has that attribute.

    info

    [RGAction] DOES NOT require using [RGStateType]. Your Behaviour will still be included as a property in the state with only [RGAction] attributes present.

    You can use both attributes when you want to specify isPlayer as true or want to override the typeName used for this Behaviour in the state.

    See Defining Actions for more information about defining actions.

    - + \ No newline at end of file diff --git a/integrating-with-unity/seating-and-spawning-bots.html b/integrating-with-unity/seating-and-spawning-bots.html index bd43bc42..83ae0f15 100644 --- a/integrating-with-unity/seating-and-spawning-bots.html +++ b/integrating-with-unity/seating-and-spawning-bots.html @@ -9,7 +9,7 @@ - + @@ -34,7 +34,7 @@ the SpawnBots() function.

    Arguments

    Argument NameTypeDefaultDescription
    clientIduintrequiredThe ID of the client whose bot is connecting
    characterConfigstringrequiredA JSON string that can be used to customize your bot
    botNamestringrequiredThe name of the bot

    Return Value

    A BotInformation object that contains the clientId, characterConfig, and botName of the connecting bot.

    Class Methods

    The remaining functions mentioned here are not meant to be overridden, but are helpful when implementing your SpawnBot and SeatBot methods.

    public GameObject GetBot(uint clientId)

    Returns the GameObject of the bot that belongs to the given clientId. Returns null if a bot is not found for the given clientId.

    Arguments

    Argument NameTypeDefaultDescription
    clientIduintrequiredThe ID of the client whose bot you want to find

    Return Value

    The GameObject which encapsulates the bot, or null if the bot is not found

    public bool IsBotSpawned(uint clientId)

    Returns true if the bot owned by the given clientId has been spawned into the game, and false otherwise. Equivalent to checking if GetBot(clientId) != null.

    Arguments

    Argument NameTypeDefaultDescription
    clientIduintrequiredThe ID of the client whose bot you want to find

    public bool BotsHaveSpawned()

    Returns true if an initial spawn of bots has occurred.

    Arguments

    None

    Return Value

    True if some bots have already been initially spawned

    public int? GetBotId(uint clientId)

    Returns the Instance ID of the transform for the bot in the scene. This can be used later to reference the bot in the scene.

    Arguments

    Argument NameTypeDefaultDescription
    clientIduintrequiredThe ID of the client that owns the bot to find

    Return Value

    The ID of the bot, or null if it cannot be found

    - + \ No newline at end of file diff --git a/markdown-page.html b/markdown-page.html index 49ccf26d..a9406f61 100644 --- a/markdown-page.html +++ b/markdown-page.html @@ -9,13 +9,13 @@ - +

    Markdown page example

    You don't need React to write simple standalone pages.

    - + \ No newline at end of file diff --git a/overview.html b/overview.html index e4f60b95..43e5014d 100644 --- a/overview.html +++ b/overview.html @@ -9,7 +9,7 @@ - + @@ -20,7 +20,7 @@ these channels, send an e-mail to aaron@regression.gg.

    • A single account can run at least 10 bots concurrently
    • The time from requesting a bot to be started to the time it connects to Unity will take less than 10 seconds if the bot is relying on dependencies that are common to most bots. This does not cover bots that may have lots of library dependencies, which may take longer.

    Implemented Features

    The table below details and links to documentation for the features implemented on our platform.

    FeatureDescriptionDocumentation
    Unity IntegrationA set of scripts and interfaces are provided to easily send state and actions between bots and your game objects.Link
    Timeline/ReplayAll bot actions and states are preserved, with a timeline/replay feature available within Unity.Link
    Unity C# SDKA C# SDK for implementing bots locally in Unity.Link
    JavaScript SDKA JavaScript SDK for implementing bots remotely in Regression Games.Link
    Live ReloadingReload bots almost instantly without rebuilding your game, managed via GitHub.Docs coming soon
    Bot Code GenerationCreate bots with low-code tools such as behavior trees powered by GPT.Link
    Platform and Language AgnosticOur protocol permits bots to eventually be written in multiple engines and languages.Docs coming soon

    Importing the Regression Games Unity Bots package

    Our package is available via GitHub here. Import the repository by clicking Add package from git URL in the Package Manager window (this window can be opened in the Window > Package Manager menu) and pasting in the following URL.

    https://github.com/Regression-Games/RGUnityBots.git?path=src/gg.regression.unity.bots#v0.0.16

    Screenshot of the package imported into the project

    For a full walkthrough on getting started, see the Building Your First Bot tutorial.

    - + \ No newline at end of file diff --git a/pre-made-bots.html b/pre-made-bots.html index 6fa5a8cd..e6937462 100644 --- a/pre-made-bots.html +++ b/pre-made-bots.html @@ -9,7 +9,7 @@ - + @@ -22,7 +22,7 @@ details. Fill out a desired name for your bot, and click create. Once on the Bot Manager page, you will see that your bot entry has a reference to the bot it was created it from, so you can always go back and reference the documentation.

    From your bot details, you can always download and upload the bot code via a zip file.

    Create a new bot View the new bot

    - + \ No newline at end of file diff --git a/quickstart.html b/quickstart.html index 56add3da..3e0ccd3e 100644 --- a/quickstart.html +++ b/quickstart.html @@ -9,7 +9,7 @@ - + @@ -27,7 +27,7 @@ will automatically open!

    Screenshot of the welcome pane

    Step 4: Run the bot!

    Once the scene is open, run the scene by clicking play. Once running, click the Regression Games logo in the bottom right, and click "Start Bot" button to start the QuickstartBot that is provided with the scene.

    Screenshot of the welcome pane

    You should see the bot move around the platform and attack the enemy!

    Next steps

    Now that you see a bot in action, you can start building your own! In the next tutorial, you will learn more about the integration patterns and approaches to building bots in Unity using the Regression Games Unity Bots SDK.

    - + \ No newline at end of file diff --git a/session-insights/client-dashboard.html b/session-insights/client-dashboard.html index 2e4aa12e..236c86e4 100644 --- a/session-insights/client-dashboard.html +++ b/session-insights/client-dashboard.html @@ -9,7 +9,7 @@ - + @@ -24,7 +24,7 @@ the screenshot will show it at a larger size.

    How To Find The Validations Page

    Visit the Running Bots tab and click on the History filter to see a list of your previous bot instances. Navigate to the Validations Page for a bot instance by clicking on the Go To Validations button.

    Validations Page Via Bot History

    Visit the Bot Manager tab and select a bot whose validations you would like to view. Navigate to the Validations Page for the selected bot by clicking on the Go To Validations button in the panel on the right.

    Validations Page Via Bot Manager

    - + \ No newline at end of file diff --git a/session-insights/in-editor-replay.html b/session-insights/in-editor-replay.html index c8ae67eb..be70e26d 100644 --- a/session-insights/in-editor-replay.html +++ b/session-insights/in-editor-replay.html @@ -9,13 +9,13 @@ - +

    Replaying Bot Behaviors in the Unity Editor

    Bots running on Regression Games save all states observed, all actions sent, and all validations performed for each game tick. This data can be loaded in the Unity editor for visualization and playback in the scene. This feature, combined with our validation framework, allows you to find and debug specific errors within your game.

    Downloading Replay Data

    At the end of a Bot's lifecycle, the replay data for every game tick processed by that Bot is saved into a single Zip file. This file can be downloaded from the History section of the Running Bots tab in the Regression Games client. Click the Download Replay Data button for the Bot instance you want to download. This will download a file named rg_bot_replay_data-<InstanceId>.zip.

    replay data download

    The Bot Replay Window

    Opening The Bot Replay Window

    With the Regression Games SDK installed in your Unity Editor Project, you can open the Regression Games Bot Replay Window from the Regression Games menu in the top bar.

    rg top menu

    Loading Your Scene

    The Bot Replay Window will render the game replay state in the currently loaded editor scene. For the best experience, make sure your gameplay scene is loaded in the editor so that all fixed scene assets will be visible and line up with the replay data.

    tip

    This replay process will dynamically create objects within the currently loaded scene.

    Don't worry !

    These objects will automatically be removed when running, saving, or building the scene. You may occassionally be prompted to save the scene because it has been changed. It is safe to save; the Bot replay objects will be removed from the scene before the save processes.

    timeline feature

    Loading Replay Data

    The first step in using the Bot Replay Window is loading a replay data Zip file. Click the Bot Replay Zip: button in the top left of the window. This will open a file chooser window. Choose the rg_bot_replay_data-<InstanceId>.zip file you downloaded from the Regression Games Client.

    Tick Inspector: Controlling The Current Tick

    After loading the file, the data for game ticks recorded by the Bot will be available for playback.

    The tick rate at which the data was recorded is shown, followed by the tick rate for playback. By default, the playback tick rate will match the recorded tick rate, but it can be modified for faster or slower plaback.

    The current tick and the total tick count are shown next to buttons for controlling the replay. You can Play the replay which will automatically update the editor at the playback tick rate. You can also manually jump to a specific tick number, or manually step forward or back 1 tick at a time.

    Tick Inspector: Evaluating The Current Tick

    For each tick, the Bot Replay Window will show all entities that were tracked as part of the Game State sent to Regression Games. These are sorted alphabetically with any active/enabled entities listed first.

    For each entity in the tick, you can use the checkboxes to enable or disable rendering its information in the scene

    • Enable or disable rendering of that entity model
    • Enable or disable rendering the path history of that entity
    • Enable or disable rendering a targeting circle around that entity
    • Enable or disable rendering action information of that entity

    In addition to controlling rendering, the tick inspector also highlights and shows a heart icon for "players" (entities that are controlled by humans or bots).

    timeline panel

    Tick Inspector: Actions And Validations

    For the entity in the tick representing the Bot Instance that the replay data was recorded from, actions and validations are shown if any were performed in that tick.

    Actions

    Shows any command(s) that the Bot sent to the game for the current tick. These could be movements, performed abilities, object interactions, etc

    Validations

    Shows any validation(s) that the Bot performed on the current tick. These are normally test cases coded into the Bot to validate that the tick data changed as expected based on prior actions or other factors in the game state. See Validation Bots (C#) (JavaScript) for more information.

    Registering Custom Models For Replay Objects

    When viewing a replay, entities that are dynamically spawned into the scene (not defined in the scene itself) need to be told what model to render with. By default they will load as a pink capsule, but they can be configured with a specific model based on their type.

    When loading a replay zip, the list of entity types to replay model associations will automatically be updated with any missing entities that have isRuntimeObject=true. You can also manually add, edit, or remove associations at any time.

    configure replay models

    tip

    The associations from entity type to replay model are saved in your project as Assets/RegressionGames/Editor/CustomReplayModels.asset.

    You can edit this asset in the inspector directly or by using the Configure Custom Replay Models button in the RG Bot Replay window to open the inspector.

    replay model manager

    tip

    While the associations support any GameObject, it is best to associate just the model for your entity.

    The replay does not trigger animations, play sounds, process physics, or evaluate any runtime scripts on your associated object.

    - + \ No newline at end of file diff --git a/tutorials/building-your-first-bot.html b/tutorials/building-your-first-bot.html index a509cba5..75c77a3d 100644 --- a/tutorials/building-your-first-bot.html +++ b/tutorials/building-your-first-bot.html @@ -9,7 +9,7 @@ - + @@ -76,7 +76,7 @@ Discord. Please note that we offer dedicated support for your integration. We are happy to work directly on your project with you, or walk you step-by-step through the integration process over a call.

    The following guides and references are great next steps:

    - + \ No newline at end of file diff --git a/tutorials/github-actions.html b/tutorials/github-actions.html index 9f639854..475a373e 100644 --- a/tutorials/github-actions.html +++ b/tutorials/github-actions.html @@ -9,7 +9,7 @@ - + @@ -59,7 +59,7 @@ contain output from your bot-code. You can also download in-game replay data which can be loaded in the Unity Editor to watch the movements and actions of each bot, as well as analyze the validations they performed. See the In-Editor Replay for instructions on how to load replay data.

    Downloads

    The timeline feature

    - + \ No newline at end of file