This in HPR episode 2007-2023 entitled, Using Elm in Context on Forex Game Client. It is posted by 2Q Toro Toro and in about 45 minutes long, and Karimak Lean flag. The summary is, 2T Toro's decision on structuring Elm application. This episode of HPR is brought to you by an honest host.com. Get 15% discount on all shared hosting with the offer code HPR-15, that's HPR-1. Bit your web hosting that's honest and fair at an honesthost.com. Hello listeners, I'm Tuka and you're listening to the Hacker Public Radio. The trick of today is writing Elm Client for the Forex Game that I'm working on. Initially when I started working on the game, I had an idea of writing it most with the HTML client set that is, and only had a little bit of scripting here and there. But as the work progressed, I had to realize that it wouldn't work very well. And there were some things that I perceived that might cause performance problems. For example, if you don't always write that, I wrote that when you open a display of all the page that was used to design the spaceships, it always called to the, it's first it loaded the Elm program and then the Elm program called to the server to load some data that was needed for the CIP construction or CIP designing. And if the user later on came to back to that side, back to that page, it did that again. But that let me, in the team, that maybe I should write the whole client in an Elm in a way that it loads the code only once and as the user navigates around the program doesn't have to load the code over and over and over again and it also could cache some data that typical, typical doesn't change, it wouldn't have to retrieve it from the server's article for example, the technology, technology, technology that tells what play has research and what they are able to build doesn't change that often, so it wouldn't have to download that from the server all the time. So all this, let me in to scripting pretty much everything I wrote with the effort using Hamlet template and look into writing the client side with that Elm. So as I said, back end is the server side is in ESOD, has close framework for left programs and the client side is written in the Elm, so they need to communicate and for that I should pre-stand up the rest interface, rest interface, so there's plenty of JSON data flowing to back and forth, the back end and front end are. It's presented in the language is the test static piping, which made it, I'm listening this current pro, project badly like it, the transfer of data in 15 minutes of course in a string, so you need to have a unit to pay or need to pay attention how those strings are handled so that the data sent from the server doesn't change something completely different on the client side, but luckily the Elm and ESOD has a pretty cool tool for this. So my goal for this was to keep things as easy as possible, keep the type safe and extensible because I don't have that clear idea of what I will be writing in a couple of months for example, and then this of course, things like user authentication, authorization that I wanted to print to the client side, too, for example you have to be able to tell the difference between regular player and administrator, administrators have the own set of use on the client side that they can use to examine the state of the system and do main demands and such things. So the typical architecture for the Elm has four major parts, these are the model, U, messages and update function, model is a single type that catches the state of the program, U is a function that when given a model will render HTML and that HTML may contain things that produce events, for example on click, handler on some link, open button and those used to create messages or other instructions that when user clicks this thing, you should create this kind of message and the message is a single type again that catches all the interactions that the programs can have, for example, user clicking on some button or program receiving update from the server or program sending update to the server and the final part is the update function that when given a model current state of the program and message will produce a new model and a possible new message to, so because of this I didn't have to really think what's the overall architecture of the program that was already given to me but I had to figure out how to make this thing a sort of the extensible, multiple pages, for example, one page to view all the star systems that the player has found and on those of other page to look into details of one of those star systems and then yet another page to look into details of a planet and to the two things that you usually do in a four x game on planets constructing things, changing policies, things like that and I decided to split this thing into pages like this, one function to render each of these pages, well I mean one function to render one page and then another function to render another page and one function to page to render the messages that it made create and then one function to elitialize the model when the page is open I put in a links into the phone also into these examples of these functions and then there's a one function to yeah the one function to elitialize the model and the page is open, this is basically the two when user opens for example a planet you for first time for a certain planet and the client has a data that is needed for it's play that information it will this function will create a point of request to the server that part of the I need the population information for the earth and I need all the buildings to allocate it on the earth and I need the things that are being constructed on the earth and those are sent to the server and when the response comes back that here's the data we store them into the model for the for example for the buildings there's a dictionary for that is keyed by the planet ID actually it's keyed by the integral because you cannot exactly you're going to put self-defined bytes into the keys as a dictionary you have to cast a cast them to integral or strings for example there's only very few data types that you can use as a keys in the dictionary but in any case those are stored in the dictionary and you can find them if you know the ID of the planet you can find buildings that are being constructed on this and the view function that renders the planet we look into that dictionary find that check if if the if there's a building present present it will render them name and level and damage I think information then it was last observed and if the information is in present it will just leave the that part of the you empty a proper to put ourselves into the data that will tell the user that the data is in present and as soon as the update comes from the server it will change that part of the you are it will help us it in a way that as whenever our model changes it will change the respective parts of the you are on the on the dome on the on the browser is our core reactive programming and LMS even functional reactive programming really it's really nice I'm very I'm very happy for work with the LM because you can always at least I have the feeling that you can pretty much always indicate things like for example if I have something that may or may not be present then the data package data type of that is maybe that thing X maybe buildings is the building system type type of the that tells me what kind of buildings are on the planet and then on the when I'm rendering on the screen there's the LM made sure that I don't just nearly will start rendering them it forces me to check that hey this is this thing might or might might not be present the compiler will tell me that you did not do that you have to do that it doesn't it doesn't type check so I have to account both cases the information is present or information is not present and that's that's captured on that type level in the model it actually it really says that this might or might not be here and as soon as I soon as the thing changes the UI changes okay so the model is split into couple parts in mind system there's the general path that holds all the common data like planets that have been the information on the planets that have really created from the star system how much resources the player has what time is it in the game things like that that can't be used pretty much everywhere and then there's a single type for each of the pages for example for the planet the I'm for the view that is used to render or the page that is so closed the planet information there's a type called planet ARR's also copy the naming convention from the year thought and that type holds the data that is needed for specifically for that page like if there's an information else that player can open or close or if there's a search field that they can to a use. That kind of information is used in that model. I mean story in that that is a particular model type. Those two together actually the latter one is part of the first one. The view function that is used to render this planet information has that function has all the information it needs to for the rendering. Each page has their own. I just want good quality view model. I couldn't think that of the name that holds that data that is specific to that particular view. And this is the one that is immediately asked by in function when a page is open first time. Okay, the message is that the type that has inventively named as a message, so open to the message that holds all the messages that the program needs to react to or send access or react to. And again in this separate message for each of those different use for planet messages for the star system, the star system message. And that message contains usually the star that only that page needs needs. Use as click the open this info panel that sends a specific planet message. And then there's a pretty message that is used to deal with responses for the queries to the server. If my system asks for it, ask the server to send information about the population on the planet. It will arrive back as a happy message, population received, and then the population received contains all the relevant information. And these are handled by the data function, either element. All the messages are handled by the single update function they come to the single function that is in charge of taking care of. Everything and if you have a big program, it can get really, really big. And that's not fun. So again, I split this into smaller parts. It's at it. Substance messages have their own hand letter. So there's still one update function that is in charge of dealing with the messages, but that can delegate the handling to the other other functions, dividing on the part of the message that actually arrived. Yeah, I think that's all about messages. So where to send messages are sent to this or rather where to this queries. I request a send to the LMAS type URL, or that is set up. The specific type of address is sent to the data. And all the functions that deal with networking use data on. I didn't want to use that because that would mean that I would have to write the frames in quite many places. And I have not said I need to do IPOs in those and that will lead into hard to debug problems because that would lead into the incorrect behavior that is noticed only when the program is running. I rather have the typos code in advance when you are combining the program. One way would be to define constants for this, but I thought that again, growing something from the years out, I made our own type called endpoint. And this endpoint is used to capture. It has all the endpoints or addresses that you can call on the server side. For example, and that type even captures the parameters that you need to send to the, you need to give to that type. For example, if I wanted to request information about population on the planet, that type that constructor I would call is an appy population, inventively named, and that takes a single parameter of the planet ID. So whenever I want to call to the server, and I want the appy population, I can give this specific constructor data constructor and the compiler will make sure that I have typed it correctly and I have given it to a correct amount of parameters and parameters of correct byte. But also, and then on the behind the scenes, I have a function that will turn this, because the L of course, there are some understandable types. I had to first of all, I had to define my own versions of, of, get post, put and delete that map to the rest behavior. And this takes this endpoint as one of the parameters, and then they understand how to get from the endpoint into the correct URL type, so nothing is in one place. And they also, that, for example, get has information of what kind of event will be, what kind of message will be created and what kind of decode or JSON parser will be used to process this data. So, when the response comes back from the server into the update function of ours, it has already been passed, the JSON data has been mapped into the L object. So, it's very nice, it's pleasant to use, you don't have to, there's a one place where you have to worry about the JSON data, apart and constructing an L object, and that places somewhere behind the scenes that you don't have to worry about when you are doing these calls. Same system is done with the data, instead of endpoint this type is called food, the idea is the same, though, root captures the different pages and parameters that you are required to give when you want to move to that page. For example, if you go to the home page, it says the home are, you don't need to give any parameters to that. But if you want to send user to our specific page about specific planet, it takes two parameters. The star system ID and planet ID, and based on those two parameters, there's a root 2 string function that understands that planet R actually maps into the string that is slash star system, slash and then star system ID, slash planet ID. So, and at the end, L, of course, the HTML function of the L, don't understand about the roots, so I actually define my own version of H, that works identically to the L, H, F, but instead of taking a URL, it takes this my food parameter and then it's kind of when it's rendering me. The stuff on the screen, it will actually use the correct L, H, F2, out to the data, to output the HTML that draws on the stand. So, there's a little bit of, there's the whole L HTML library that is free, good, and a couple of little additions that are specific to the system, and that's R, yeah, and that's R, yeah, the since 0.19 version of the L, the L program can be made other of on what URL is it is being run. So, this allowed me to draw the system in a way that that the server, the yes-out will serve the same L program from multiple locations, for example, if you, if you go into the homepage, it will serve the same L program as if you went to the, for example, planet page or star system page or page about messages, the all will serve the exact same L program. And the L program itself is aware of URL, where it was started, which allows it to, in the start, to move to that correct view, it will render. For the user it will look like they are, they are starting from a different different pages within the program as they actually are starting from the different page, within the program, but it's still the same L program in every, in each and every of these cases. I made this because it allowed me to, for example, this allows players to keep links to other players. If they, if they have opened a specific planet, for example, they can just copy the URL, mail that URL to another player and say that, hey, have a look at this planet. And if that, another player has sufficient information, they have, they have observed that planet at some point, opening, opening that a, URL will give them the correct view, they can see the same, and if they are members of the same action, they are getting the exact same information, even, of course. I had a feeling that it's important to, even, even when the program, even the clients had a single program, it is important to keep users' ability to send links to other users, and have those links work in the way that they would work in a normal, normal, that, not, not in our case, not in our, because in some cases, there are those single-phase applications, where you cannot link into a subview, and I don't write those, I think that, I think that the ability to link to a specific point in our system is our, very crucial integral part of the level. Okay, and, yeah, and, now, let's move on. Okay, there's a part of this, that was, a record for this is the, the, we have the function, rule to string, that, when given a rule, will give you the, correct, string that you can use in the URLs part to facilitate the mapping from the another, another direction we have, we had to create a mapping that tries, when given, are any kind of string, as a URL, will try to figure out what, what, root, that, this will be, and part of that, nothing for this is defined in the function root, that, I have the definition of that in the URLs, that only, that basically, that if there's a, for example, if there's a string profile, nothing else, it will not do the profile page, within the program, if there's a string star system, star system ID, slash planet ID, it will not do the planet R resource, or root, sorry, root, and then the top root, home, R is used when passing fails. So whenever use a, for example, if use types the URL hello world, it, it will take them to the home root, and, not else, the platforms, yeah, there's a part of the, the really, this, this one, and actually, the proud of, I listed the basic idea from the yesterday again, but in top of the top of the page, there's a track comes, this is just a hierarchy of navigational 8, it displays names of the pages that are earlier, and not early on the history, but sort of an above of this specific page that uses currently, when they are at the very beginning, it shows just a home, I've picked, but if they click to the, let's say star systems, the platforms will fit home, slash star systems, and now home is a suddenly a link that you can click and get back to the whole page, and on the star system page, the uses have a list of star systems that they are of, all these data that the client is showing is based on the, on the reports that have been generated to the gameplay, I talked about those earlier, those, those reports are just telling the use, use that, this is how you observe them, how you observe the word, this is the information you have, and the client is dealing only on those reports, the client never ever sees the actual data about what's the real state of the word, but I got the most, so when they click a, for example, a solar system, now the platforms will create home, slash star systems, slash solar, not star system, not general name, but solar because that's the current system they are viewing, and home and star system texts are links to those respective pages, and now the use are, so on the items of the solar system, there's a list of the planet that they are of, is they click the earth, they are taken to the page that shows the divers of the earth, and now the platforms will feed home, star systems, home, slash star system, slash solar, earth, and all that the earth are links to the, to the, to the, to address the pages, this, the idea behind here is that the users are, they are aware of, where they have navigated, they, they have some sort of contextual information of the location within the system, and they are also given a tool to quickly jump back to somewhere, they can use, browser, back to them, LLM, the, LLM program will detect that now the, now the, has requested moving to a different URL, and we'll test the correct page, we think the LLM program, you don't, you don't actually exit the LLM program when you hit taco forward, in the, in the, browser, until you go all the way to the back, and you go back from the, they, you started from the, the LLM program, then you, of course, lift the LLM program, how, how, how came client and freedom to, for the, do do disclose the side page of your browser, for example? So the press comes, are, offered another way, you don't have to use the back button but you can directly, even if you're doing the, third you can directly jump to the home base of the, of the game, client are just clicking that And these are defined, well, this will be a little bit of functions that are not interesting, but the thread cramped, the uncoly thread cramped path, the whole thing is made in a data function, thread cramped path, that takes the model and produces HDML, that's the whole whole thing. And that also wraps it in a some diff and styling and whatnot. The actual word word is done in a function called thread cramped, that takes a model because you need to know where you are, you need to. And then there's the pool and flag which tells you if you are on the first node or in some another node, then it gives you the current root, that you want to construct a fragment from and it will produce you a list of HDML. And this will call itself recursively, recursively, the first one is called with the flag being. Actually, I don't remember, I have to admit, I don't have to code, I have only that definition here. I think it was called with a pool and we drew, say, meaning that this is the first element. And after that, the recursive code will turn the pool into false, but I'm not sure that which of course means that I should get rid of the pool and flag and have a real pipe there, pipe that is, for example, the platform placement that can have two values, first and some other, because then it will be visible on the pipe definition that what this pool and flag is, actually used for, it would have a sensible name and it would have, well, if we don't have any more values or any less values than the pool and what it, it would have a sensible name and it would have a pipe and it would mean that you don't accidentally stop something in correct way. Oh, it would, at least it would make it harder to put something in correct way. And that, that thing is calling third function called segment that takes the model root and produces a couple of string and maybe root. The string here that it produces is an actual text that is being shown, for example, in case of the home page, it just reads home, in case of the far system, it reads star systems. In case of the earth, the planet earth, it will read earth. And for that reason, the function needs the model because the model holds all the data that has lags in reference from the server, it has that dictionary, that has the planet information and that dictionary is keyed by the planet ID, the integral actually, because you still can't put that. Client ID is in the case of the dictionary and based on that information, the segment who understands that, now we are on a thicker food, root is of course, the planet R that has two parameters, star system ID and planet ID. Based on that information, that and the model that has given the segment can read for you from that dictionary that is in the model, the information of the planet being currently shown and get the name of that planet and put that written by the way, this is not just any planet is the planet earth. And the second parameter on the top of that is written is the navy root. And that is used to indicate the parent of this segment. In the case of the home, it's nothing because there's no parent, but in the case of the, for example, if we are navigating through the, we have navigated to the view of what earth, the parent will be star system, or with a correct star, with a correct star system ID. And this will trigger the recurrent recurrent in the threat function because it notices that the case has a parent, so it will call it, it will call the segment again and in the root it will give that star system a star meter, that will produce a top of it a string as a sole and just a star system, a star meter. And that will trigger the recurrent in the again and from that source and you are getting a home actually, a home and nothing because home doesn't have a parent anymore. So then, whenever you are, whenever the user is interested with the system, the threat count part, when given a model will produce a list of all the, all the pages and the names starting from the home ending to the current location, or starting from the current location, ending to the home which whichever way you whichever you want to view. That was, that part of the program was going to find a code I like, I like that. And as I said, I listed a post is from the years outside. That's quite a bit. I feel that there's quite a bit neat things on the years old that can be done, that can be used in other systems and I have been using them on the helm. There's a, I like, like I said earlier, you cannot use star system ideas, planed ideas, basically self-defined types in the, as a piece of the dictionary, that's limitation of the air, that's, I have had couple packs of, because of that, because there, I have just a dictionary with a key, a index, and the index, of course, doesn't tell you what it is used for, it's just an answer. But everywhere else in the program, performance, I'm not, I'm limit, I'm trying to keep the use of primitive data types to the minimum, instead. So all the places where I'm talking about planet, planet ideas, the identification of the planet, it's the planet ID type. That, if they, that only, rather, index, but it gives, it, that, rather, gives the meaning to the index, and it gives, gives you mixing the planet ideas, for example, with the star system ideas. And the, same thing with the resources, I talked about the resources on the end, right? Sorry, on the, on the years old side, and on the elm side, there's a similar system. I think, I couldn't figure out if, if one can use phantom types, I think you cannot yet, or we'll never be able to, but I still have, I have, I still can have resources, but that has a three type of resources, the biological resources, the magnetic resources, and the chemical resources. So at least I'm not going to mix biological resources and magnetic resources with these, I might mix them in a different context, in a, in a way that, for example, I would mix the construction speed with, or resources with, uh, with the required amount of resources, and things like that, but, uh, still, I'm, sort of happy, how the resource handling is, and on the, the resource handling is not, not, not, not, not, not, not, not, not, not, not, not, not, not, not, not, not, not. I, uh, can have resources, that's what the player uses to, to construct things, and, and, and, fair, happy, how it's handled on the, inside. That, though, probably, I missed quite a bit while trying to explain, but, if, if, if something else comes to mind, I'm, I'm, record on near, New episode, I'm going to have a feeling that if I keep working on this game, it will take eight, it's like years and years to get it somewhere somewhat playable space, but it's a fun project. I'm having lots of fun trying to learn the hospital and ailment, lip programming and whatnot. So I will be interested to hear if you have any experiences, experience on ailment, how you or how you like to blend with so far, it's a really young language, and if you have experience on the ailment and some auto of this new language is like pure script, or even some you have a script for your works like react, and how and ailment if you can talk about the differences and the similarities between them, I will be extremely interested in hearing those on the head about the radio, but this is talk about this, what's quite a long episode and trying to keep this a little sore in the future, so have a good day. You've been listening to Hecker Public Radio at HeckerPublicRadio.org. We are a community podcast network that release the shows every weekday Monday through Friday. Today's show, like all our shows, was contributed by a HBO artist near like yourself, if you ever thought of recording a podcast and click on our contribute in to find out how easy it really is. HeckerPublicRadio was found by the digital.com and the informomicon computer club and is part of the binary revolution at binref.com. If you have comments on today's show, please email the host directly, leave a comment on the website or record a follow up episode yourself. On this otherwise status, today's show is released on the creative comments, attribution, share a like, free.au license.