 Hello again on the remote congress, another day in the Hexen stream. The following talk will be with David Negrier, the main developer of WorkAdventure. The little world the whole congress is happening in. Some may be watching about inside the stream and some may become around in the world. And David will tell us some details about WorkAdventure, how to make unexpected things inside. And have a lot of fun in the talk and there will be a Q&A later on in the room. Ada, again, you will have the link in the end of the talk. Thank you. Hi everybody, I'm really happy to be here with you today as we will be talking on how we can hack WorkAdventure for fun and profit. So I'm pretty sure you all know what WorkAdventure is about because it is a virtual universe that is taking place where the R3 world is taking place right now. So the little characters moving in the virtual universe is based on WorkAdventure. So today we're going to see how WorkAdventure was built as an open platform and what it means. It means that we can try generating dynamic maps but also we can try scripting maps. And scripting maps sometimes has limitations so we're going to see how we can hack around those limitations to open more possibilities. Cool. A quick note about me, my name is David Negrier. I'm the dad of WorkAdventure. I started the project like one year and a half ago during the French lockdown. And I'm a little developer. So what does it mean for WorkAdventure to be an open platform? Well, apart from having the code on GitHub, if you've been designing maps for WorkAdventure for the R3 world, you had to submit the maps and they had to be validated because R3 wanted to have a coherent experience. But the fact is that when you're doing pure WorkAdventure, you don't have this acceptance and you don't need to validate anything. And actually if you look at the URL of a map, it looks like that. Here you've got what looks like a URL inside the URL, right? And well, this URL here is actually the URL of the map that is going to be loaded by WorkAdventure. So how does it work? There is a server, there is a browser running WorkAdventure, and they both load the map from any web server anywhere in the world. So if you want to design a map, you type tile, this is the map editor. It generates a JSON file. And this JSON file, you can put it in any web server. And the only thing is that the web server here must have course header properly set. This is really important because otherwise the browser will not be able to do an XHR request to the server. But as soon as the headers are set, you can really put your map anywhere. One of the fun things is that you can actually use GitHub because it has a service called GitHub Pages that acts as a free web server. So if you don't have a web server or Raspberry Pi at home, you can use GitHub Pages. And since it's on GitHub, you can also use Git workflows like making pull requests and stuff like that to work as a team on your map. But this is really static files. And since you can host your map anywhere and a request will be made, you could also generate your map dynamically. And this is where the fun is actually. So you can take any web server, not JS, PHP, Python, whatever, and generate a file. So in order to generate this file, the first thing you have to know is, well, how to generate it and what is the JSON format for this file. But hopefully, this is well explained in the documentation of Tile. So here I put a link to the documentation. It's quite self-explanatory. You've got layers. You've got the tiles. You've got tilesets. It's actually kind of quite easy to use. And once you understood the JSON file format, what can you do with it? Well, this is where the fun part is and you have to figure out actually, but for instance, you could try to generate a map that is changing whether it's raining or whether outside is sunny. You could generate a map from OpenStreetMapData. You could make a map that contains an art collection based on the NFTs you've got. I don't know. Really, it's up to you to find a clever hack, actually. But there is a few things you need to know. Since WorkAdventure is loading the map once, well, if the map is modified after it has been loaded, WorkAdventure will not notice since the map is uploaded on another web server. So if there are any changes, you will need to refresh your page so that the map is reloaded. And also, this means that you could try to present different maps to different players and they would see different maps and still be moving on to parallel universe. You can actually take advantage of that if you want, for instance, to open a door for some users and close it for others. But yes, these are kind of limitations. Still, you can do pretty amazing things. And here, I've got an OpenStreetMap demo that has been developed by Jonathan Eindel, which is a really, really cool hacker. The guy is absolutely awesome. And, well, let me show you. Here, I'm connecting. And, oh, okay. So I've got my little Pac-Man character. Well, if I move here in a place, well, you can see that all this data is actually fetched from OpenStreetMap. And if you have a look at the URL, what is really, really fun? I've got a latitude and longitude parameter here. And if I modify those a little bit and if I refresh the page, it's going to dynamically fetch data from another place. So it's running on his Raspberry Pi at home, this map. So it's a bit slow, but hey, look. So I've got another place and he built a database where you can actually put entries and exit a bit everywhere. So, yeah, it's a really, really nice hack. And, well, I was pretty amazed when I saw that. Yeah. I've been speaking about putting entries and exits just before. You saw that from one point I could go into another map and in WorkAdventure, we do that by actually putting a property which we call exit URL inside the map. So on this layer here, when I walk here, I will go here. And this actually is, if you think about it, pretty much looking like an hypertext link on a web page. And even more, we've got what we call entry zones that we define using a star layer property. And the name of the layer here is down the stairs. And if I go on the web page and I'm adding dash down the stairs here, I'm actually entering the page at the very position of the layer which is kind of fun because if you think about it, well, WorkAdventure map are JSON files that can be hosted anywhere on the web, just like HTML web pages. And exit and entries in WorkAdventure map, they are my mapping, hypertext links, and anchors on the web. And so that leads me to think of WorkAdventure not only as a platform, but rather as a browser. I see it as a browser of maps that could be anywhere on the web, a bit like a web browser enables you to navigate HTML web pages. And this was actually the state of WorkAdventure in December 2020 when we did the previous RC3. And it was already like that. The fact is that since last year a lot of things happened. And the first of things that happened is that we had a lot of cool contributions thanks to the Chaos Computer Club because it provided us a lot of visibility. A lot of people came, started hacking around, making pull requests on the main repository. And basically, yeah, it blew up. We had a ton of new features. People provided us with zones where you could play sounds or music, animations and maps, emojis, components, cats and dogs are cool and they have actually been implemented not by me at all, but by the community at large. And someday some guy came and said, hey, look, I've got this excellent pull request and it allows you to play animations when you get next to near an object. And the animation can optionally play backwards and I was like, what? And the fun thing is that the rest of the community was like, oh, yes, yes, yes, this is a really, really good idea. Actually, what this was allowing to do was like when you walk on the grass, the grass can move, so it's cool effect. And it was indeed cool, but for me it was also kind of a problem because, well, as a maintainer of an open source solution, if I was accepting too much things, I would have to maintain them. And especially because I started hosting a work adventure software as a service solution online, I could not afford to do any breaking changes because my users, if I change the format of the maps, they won't be happy at all. So basically, if you think about it, the need that the developers were expressing was they wanted to be able to treat cool stuff with work adventure. And I had a need to restrict a bit the number of pull requests I was accepting, otherwise it would get difficult. So how did we do? You remember this comparison between work adventure and a web browser? Well, there is something with a web. It's like actually you can modify the JavaScript with a DOM. And in work adventure, that we could not do at all. And this was a real problem. So what I wanted actually to do was to open the ability here for people to add scripts into their map to be able to build cool stuff. And with scripting, they could be really creative without having to add new properties all the time. Okay. But in order to do scripting, I had an issue that I have a big need to isolate the context. Basically, if someone is providing a map and if I'm running a script from the map inside work adventure, well, I'm running JavaScript into my web page and it could definitely be XSS a cross-size scripting issue, which is not good. So I need to protect myself against that. So how did we do? Well, we used iframes. Because when you run code inside an iframe, it's isolated from the mainframe, right? So if you think about it, you've got the browser here. There is a map and on the map, I'm hiding a very, very small iframe. It's one pixel by one pixel transparent. Nobody can see it, but it's here and the iframe can contain JavaScript code that is run. And the fact is a JavaScript, the iframe can communicate with the browser using what we call the PostMessage API which is a native API that is available in any browser and it's a communication mechanism between iframes. So if you look at it, it's really easy. You can send a message using window.postmessage. You put any JSON message here and if you want to receive a message in the other frame, you just add a listener on the message event and you get that message back. And since these are JSON messages, well, you can build a format and check the format and the communication is clear and well-defined which is important when you want to do something that is secure. But I still had a problem. The iframe I was creating could access the DOM of the parent element because it was hosted in the same domain. Okay, my iframe is created on the fly by my application. So it is hosted in the same domain which means that because of the same origin policy, the iframe could access the parent frame, insert a script tag and so, basically, will open an XSS flow in my application. So I had to protect myself from that. And the solution to that, it's little known that on an iframe you can use an attribute that is called sandbox. And the sandbox attribute, it lets you decide what an iframe can do or not. As soon as you put the sandbox attribute, the iframe is really restricted and then you open what it is allowed to do. So I'm allowing to run scripts because I want to allow JavaScript. But with just this, the iframe is losing its origin. Okay, it does not have any domain anymore, which means that if it does not have any domain, well, the same origin policy applies again. The iframe cannot access the parent iframe and I'm good to go. And this is pretty cool. So what you can remember from this is that if you use the first message API with an iframe that is sandboxed, you can actually run into your application some particle, some particle code, code that is coming from someone else in a secure way and without the code risking to have too many impacts on your application. So what we did after was hiding the complexity of the window that passed message behind a friendly API. And the result is this. Here is a sample script. I've got this WA object that is a global object. And here I'm listening when I'm entering the zone which is named clock, which is here. And when this happens, I'm opening a pop-up that displays the time. So it's a small example of what is possible to do with this scripting API. So yeah, it's pretty cool. And there are already many things you can do. You can read a map, you can show and hide layers, edit a layer to add a tile on it, load the tileset. A lot of stuff. And there are still a lot of things that are missing and that we are adding every day and the community at large is helping us. But there is one thing I want to stress out. It's that because the script is executed in the browser, changes that are applied are applied only locally. And especially if you edit a layer, add a tile or something like that, by default, this is not shared with other players. So we need to add a communication mechanism between my player and the other players in order to dispatch messages and so that people can see the same map. And to do this, well, we added a feature that is called variables. So variables are stuff that live on the server. And in a browser, when you use a WA.state object, anything that you set here will be shared with other browsers. What happens actually is that when you call this, the foo.equal.bar message is sent the post message API to the browser. WorkAdventure will dispatch this to the server which will dispatch the message to other players which will send the message back to the other iframes. And hey, here we are, states are shared and we have the same values in both places. And additionally, you can even listen to changes using unviable change here which allows you to fire a callback when a variable is changed. So with this, we can share a state and so display, for instance, if I've got a door, it can be opened or closed depending on the state of a variable which will actually show or hide a layer. We have a lot of things to add in the scripting API. We need still to be able to track other players. Really, really a lot of things to do. But the cool thing is that the community understood that and that most of the pull requests received from the community are now made to change the scripting API and to allow everybody to have fun and to build cool stuff with it. Still, there are some limitations. As I told you, the sandbox is often getting in the way because the sandbox iframe does not have an origin so it cannot make any XHR calls because when I do an XHR call, I need an origin and I can't do that anymore. And this is really a problem because often when you script a map you want to be able to connect to something else. So is it really possible? Well, I'll show you how you can hack around this limitation. And the first trick is actually using WebSockets because surprisingly enough, I was not aware of that WebSockets are not bound to the same origin policy as XHR. Anywhere, in any web page, if you open a WebSocket you can connect to absolutely anywhere, which is pretty cool. So it means that from the scripting API here if I open a WebSocket, I can connect to any server here. So a server icon and to share state, to get data, whatever. But I can do this on WebSockets instead of doing this with XHR. The second trick, which is actually maybe easier is to use embedded iframes. Since a few months, you can create iframes and put them inside maps. And those iframes actually... Or those iframes actually... Well, they are hosted on any web server and they are not in the same web server as WorkAdventure is. Which means that because of the same origin policy they are not in the same domain, they cannot access the parent frame. And if they don't access the parent frame I don't have to put the sandbox attribute on this iframe. And if I don't have to put the sandbox attribute you keep your origin and you can do an XHR request really easily. So my advice is actually if you are building a script with WorkAdventure rather than using the native script feature you put a really, really small iframe. You hide it inside the map. You put the script inside the iframe and you will be able to make much more things with the native solution, which is kind of interesting. Okay, quick demos. The first one is done by Jonathan. Again, it's a minesweeper. I would never have expected someone to do something like that. But as you can see, if I press space, I can see here, well, I can play a minesweeper and I can, of course, blue on mine. Which is kind of fun and this has been completely done with a scripting API and I designed that to open and close doors and suddenly I've got a full game in it and overall I find that really, really, really cool. And the other demo is a work one which is been done by Jacques Olivier and Vincent. And you can play the video at this point. And, well, as you can see, well, it's a Pac-Man clone where you can eat Pac-Guns and you can, it's a multiplayer game and if a ghost is catching you, well, you lost. Yeah, and this has been done, well, also completely with a scripting API and a lot of cool hacks to overcome the shortcomings of the scripting API. So, yeah, so tomorrow, but, well, what are we going to do? Well, I very much would like to make work adventures in Ultimate Sandbox. So I'll try to keep working on this API and opening more possibilities. And if you want to play with me, well, you're welcome. Everything is on GitHub and I would be really, really happy to see what amazing hacks you can come up with. So was that it? Well, I hope you enjoyed the talk. I would be really happy to speak with you about it on the Arcistry world. If you're looking at a replay of the video, I'm also in my virtual office, usually at workadventure.re slash demo. And if you want to come and talk, I'm usually there. So, well, don't hesitate. Thank you very much for watching and see you soon. Okay, bye-bye. Yes, thank you, David, for this interesting talk about work adventure. A lot of people, we are creating the world. We are inside this Congress, walking around, experience interesting places, working on that all the time. And now we have some advanced information. We can make this place even better if we need another virtual event or let people take place over the internet. You can join the Q&A if you have further questions on this, events.hexen.org slash awesome downslash Ada. So please and contact us in our Q&A. You can also use a QR code to get inside and we will change over here right now. Thank you very much.