 Okay Sorry the screen resolution on this is not great. You really can't see this I knew better than to use a dark image is my first slide, but yeah, I did This is the ruins of a space station. You can kind of see little bits of their Transmation space up behind it And the reason for that is we're gonna talk about building a universe in Pearl and I was actually gonna give a talk about testing But the organizer said would you talk about tau station given tweeting about it a lot people are very interested in it they want to know more about it and Then I found myself in the very awkward position of I'm at a free and open source conference How can I do a 40 minute talk about a commercial product without a starting like an infomercial? That one's a little awkward So I think I can actually pull it off and by the time I'm done with this talk You're actually going to see some things that you might want to bring back to your own code So regarding questions, we only have 40 minutes quite often and positive We run very short on time unlike what you had just seen So please hold your questions to the end and I apologize for that I know sometimes you want to interrupt because there's something you don't understand But this time let us hold our questions till the end to make sure that we don't accidentally run over time here So when I say the universe, what do I mean by this? So tau station is We it's you could say it's a text-based MMORPG This is a little bit of a problem. We found when we say MMORPG people tend to think game Which it is but they also tend to think graphics We've actually had one person asked, you know, how can you be an RPG without graphics? And it's like you never played D&D as a kid. Did you? Or tech space people say, oh a couple of junior programmers can whip that out in a month new so that's why we say a universe because we're trying to do something we're trying to reframe the idea so that people understand it is bigger than You know something simple like a multiplayer resort, you know our mud So oops, so it runs a book browser and mobile. We actually we do a lot of mobile first design We don't just make it for the web browser and resize it down for the browser for the mobile we try and make the mobile actually work properly and We also use progressive enhancement rather than graceful degradation because graceful degradation is well crap Because people forget about the degradation part progressive enhancement means that we can build an accessible application So I don't know if any of you are familiar with this problem with Some facial recognition software it often doesn't recognize people of color Why because a lot of people who are not of color have been building these applications And they don't think about skin tones or how they might look in the background And so you see some things on YouTube and other places look at this facial recognition app Which doesn't recognize my face Now if you wrote the developer and reported this as a bug and they said well actually black people are really small demographic We don't care about them. There would be an uproar If you write to them and say blind people can't use your application and they said well black blind people are a small demographic There would not be an uproar because nobody cares We're writing a text-based game. We actually think this is important We do understand accessibility can be sometimes challenging for some companies to do for their applications But we are trying to make this as accessible as possible You'll see some examples so that blind people can use it or if you use a sip and puff device for navigating a browser Or just have a clicker all sorts of things like that. We're trying to make sure that anybody can play this game Regardless of who they are It's also free to play. I don't know if you're familiar with the free-to-play genre of games But for the politics of some of that we don't have level caps. We don't have pay-to-win It's premium accounts micro transactions, but anyone can participate. We want it to be as open as possible for everyone And the story I'm just gonna kind of be brief about this basically it's far future around the year on 2600 about 600 years in the future humanity had a post scare city society had spread throughout the galaxy and Then the attack happened Planetary defense systems turned on the planet Airlocks were being vented ships reactors went critical data banks were being purged Most of humanity trillions were dead in a matter of hours and then it stopped And no one knows why it's an event called the catastrophe two generations later humanities restricted to a sphere about 40 light years across They don't know how to build new technology anymore They've lost a lot of that knowledge, but the old technology was robust enough that they can repair a lot of it So if you if you want to try and force it into a genre you can kind of think Mad Max meets firefly The universe itself it turns out within 20 light years of earth there are 117 stars that we know of That's an interesting caveat because it turns out it's trickier than one might think we have over 500 space stations over 8,000 stations So there's a lot of stuff It's we're trying to build a universe here not just a simple game where you just click and drool and whatever The alpha we're hoping to have it around the summertime It's obviously to be much much smaller in the alpha It's gonna be invite for people who sign up on our website It's only gonna have 14 stations in soul and alpha Centauri It should have about 200 areas maybe a hundred missions available for the thing Obviously, some of the features are not going to be available at that time That's just getting us an idea of the initial feedback of what people think about it But we also have art which once again, you can't see very well Unfortunately, I should not take dark pictures for this But because we believe even though it is a tax-based game We also want it to be a very pretty professional game. So here's a character screen. This is not a mock-up This is real from the game. You can see it looks fairly nice fairly professional. It is a dark theme After launch, we are going to have a light theme in there for people who prefer those We actually track a lot of information. So here's a full character screen I had to shrink it down so you can see more of it That gives you an idea of the amount of information we might be capturing for your individual character You might want to take a job There's all sorts of careers available in the game in the far future. Obviously jobs are going to be a little bit different We have missions. Our mission system is non-linear except for dialogue Dialogue nodes is what we call a direct-to-day cyclic graph for those of you more of a comp side-bent This is not like World of Warcraft missions go out pick ten flowers come back We have Complicated missions sometimes where there's all sorts of things and we don't always tell you what those other things are If you get a mysterious package to deliver to R.V. Nouvelle-Marche We don't necessarily tell you that there might be something else you can do with the package But there might not be you won't always know and this is actually a fairly simple mission Some of them are just mind-bendingly complicated and you won't always know because you'll just take a straight path to the mission But we want to have that complexity available so people can enjoy exploring different facets of their character making different moral choices and some of them are pretty Mind-bending at times, but as you do missions, you might get money. So you want to put your money in a bank Because you might get mugged people might take the money And if you get mugged you might wind up in a sick bay or if there's no sick bay on the station You're gonna fall back to your latest clone if you elected to get a cloning license This helps you avoid permit debt, but does have other consequences, which I won't go into right now You can relax in a bar after work But it's space opera. It's sci-fi you want to go to the stars. That's what you want to do You want to travel around you want to see what's out there? So you go down to the port And you hop on a spaceship Obviously multiple different types of spaceships this by the way, it's a star map I wrote this in JavaScript. I was pretty proud of it and then our front-end developer said your JavaScript sucks and they rewrote it They were right you can't tell from this unfortunately, but the colors of the stars are astronomically correct I keep wanting to say anatomically correct. That's awkward The colors of the star are astronomically correct We might actually punch up those colors a little bit because it's hard to see But we think that's important because we do like to pay attention to a lot of little details We won't say it's hard science fiction, but we're not offensive to science This is what the star map looks like if you don't have JavaScript enabled or if you have a screen reader or a Text-based browser because it's accessible that star map is a useful thing that you can click on if you just have a little clicker With your mouth clicking around you're not going to be able to click one of those stars So we have this available in text form. It's much harder to use But unfortunately, that's one of the trade-offs you have when you switch to a different medium It is available for people who have various disabilities The games work in progress This is a game flow diagram of the port anything in red either is in progress or has not been started yet so we're still working on the thing and we might have to pull back some features because The shows like run April the done date you can see our burn down line is getting beyond that So we're working on trying to fix that I Needed to explain that so you can understand the complexity the scale of what we're doing This is big. This is complex and it is not like your standard apps For one thing is very right heavy Kind of build a right heavy database applications a little bit more difficult But our guidelines is first of all we use proven technologies. We don't want to experiment We don't want to take chances or some really really cool Applications out there that we've been looking at we thought that might make things really fascinating new We want to make a product that's actually stable. That's robust that people can use We don't want the hype so we stick with proven technologies very careful about our hiring for our clients We promise all of them they go through our software test And they also go through what we call a structured interview to make sure that they have the skills that the soft skills that the client needs And we do the same thing internally hiring for tower station. It's just given us fantastic developers for the project Very happy about that and very strong testing As most of you know, I have been testing a time or two. I care about it. I have a manifesto I call the zen of test suites which is out there. This is not yet a slideshare. I'll get it up there So you can get the links later. So testing I'll talk about that first just a little bit I won't show you any of the code, but you'll get an idea of how we approach testing So does anyone here use test class moose? Okay, I see a couple of hands up there. Well, of course you do Jeff. You're working on it So test class moose Test class most was a project that was released directly out of this project veer was the code name for it So test class most came out of that and later on people kept asking me how do I mix moose and test class? Well, you can't because they're both fighting over the constructor So I just wrote test class moose based upon my experience of test class most So those of you who are using test class moose and I know a lot of larger companies are because it's a fantastic Testing framework that comes out of this So we're trying to give back to the community when we can even the code itself has to be closed source because we have to protect The secrets or else it ruins the gameplay So that's a frustration. We'd like more to be open source. We can Selenium's there a load testing I Wrote the load testing bots in Pearl And it wound up crashing my box before the dev server so I want to rewriting those in Golang and Now they will crush our stack quite nicely Golang's really sweet. I might add We have almost 11,000 tests at this point and we track our test history More people need to do this Let me give you I'll go to the test history just a moment. So our test guidelines I won't go over this if you go out and you Google for Ovid Zen of test suites You'll find it but the test guidelines are very clear We want our test to be easy to write easy to run and they're they're really nice And our test suite looks kind of like this. Oh my goodness. I won't do this again I promise Well, you will see it again in the presentation after this. I've learned my lesson. So that says 1,776 tests. That's not true Test class moose is an x-unit framework and an x-unit framework You have test methods with a bunch of assertions inside of them and the test method is considered a single test in the pearl world We have a test method with a bunch of tests inside of it So we have a test report which comes out which shows we have about 9,037 tests if you add it up that's around 11,000 tests basically And the report also shows us our slowest test classes and our slowest test methods So we can keep an eye on where our performance bottlenecks are in our test suite And the entire test suite on a fast Linux box You can finish it in about five minutes most people it's around eight to ten minutes But five minutes I think is rather interesting for 11,000 tests because I remember when I first started for the BBC We had a test suite of comparable size and it took an hour and 20 minutes to run Most of the time when I go into clients they say we well our tests We're not running them very often our test suite's broken if they've got a test suite anywhere close to the side Just taking them around an hour. That's awful So we're not doing that at all. We've we from day one. I said that ain't gonna happen and it's not But you might wonder what's failing in your test suite so I can we track our tests our test suite state and We run a little program called test failures dot pl and it shows us all these test failures So we can see the class I've truncated some information so it's it'll show us the class It's failed the name of the test method that failed the date that it first failed the date that it last failed and the number of errors and Wow, that's a lot of errors. We have there. That's actually kind of disconcerting. Oh Well, let me just maybe I should just look at the test failures on master So I restrict this to our master branch. We're using it and You can see the number of test errors that we the errors in our test suite for master branch have dropped dramatically And actually so you can look over here two of those failures. You can't read it there I apologize to the failures reference reference the leaderboard So this allowed us to understand that our leaderboard is problematic We've got a number of repetitive test failures there. We've looked at our leaderboard We understand the problems of the codes that's being rewritten in order to get around this problem This is what tracking test state allows us to do. We don't forget about those past failures But a lot of these last failures the dates in 2016. So let me just look at the last two weeks I have four errors in the last two weeks on the master branch and it's testing a respawning an MPC after they died So and actually we understand what that is This is what this is why we pay so much attention to our test suite because we want stuff to be robust And we can check a lot of information over time. We also run this on our Jenkins box So our Jenkins box also has an SQL like database tracking all of the test failures over time the major tools that we use Just about all of these are open source The only one that's not is JavaScript JavaScript is open standard. It's not open source, but it's close enough So we're using pearl 5 version 24. It's very important that we have a lot of the modern tools available for us Go lang that's just for our load testing box postgresql because we need a real database Skits for our database management Redis is used just for caching if our redis server goes down it would hurt gameplay, but not kill it It would slow things down. You'd lose a little bit of information, but it's not critical to it Fluid the elastics are to get Jenkins, you know usual suspects nothing Exciting about this list and I think that's great because there's not a lot of risk involved in it MVC Catalyst template toolkit Dbx class again. There's nothing exciting about this very conservative in our approach to how we're writing code to make sure that we can Actually focus on delivering a product and not debugging the latest thing and the greatest height that just came out What does MVC look like for us? This is one of my greatest frustrations. I have with tutorials for MVC First of all, I'd like to see MVC renamed web MVC renamed to ABC application view controller Because the model I like to think that more is an application and then you have a controller and a view on top of that Let me show you what I mean there So here's one of our controller methods for the clone that so you go to a clone back You can purchase a new clone and they will just state the new clone for you if you have enough money And if you're actually in the clone that Very simple method This is what we strive for in our controller methods. No logic. We do not want logic on our controller methods More to the point thin controllers. Damn it The reason we don't want logic in our controller methods is first of all when you write tests for that and your error is 500 What was that can I get a stack trace? Well, sometimes that's very difficult when you're going through, you know Using dub dub dub mechanized or something like that to dig in there to find out what the actual error is You have a whole layer of stuff which is irrelevant to the error in question that you have to dig through to get down to the actual Error, so that makes it frustrating when you're testing and also It's hard to reuse the logic quite often that you have embedded in controller methods controller methods Just think of them as your API. You don't put logic in an API. It just dispatches between the view and the application And in this particular case if you purchase a clone, we don't have an independent page We just give some messages back to the character and we need to go back to the main clone that page So we just forward back to the index our controller methods. We strive to get them as simple as possible And This is what a clone method can look like now bear with me. I don't like to put a lot of code on a slide I apologize for that. Let me walk you through this. So you want to say what's going on here? This is our clone method first thing we do is We croak if they're not in the clone back Actually, we don't we log the error, but basically we have to make sure they're in the right area in order to clone We check to see if they have enough money and then we start and end Transaction there we remove the money from their wallet and then we do the actual gestation of the clone And then we send a message back to the character letting them know what happened There's actually a number of problems with us, which I won't go into right now but the biggest problem we have is so this is the Result you get back you purchased a new clone how much it cost you and then you know some Narrative text about a clone swelling up in the clone that or whatever That was ugly code though Because look at all of that. So this was actually in our clone In our clone class and our clone actually shouldn't be rummaging around in the character's wallet The clone class shouldn't be caring about the area of the space station that you're in Clone class should be just just stating a new clone. There's a real confusing mix of responsibilities there. So and plus All of this stuff if I'm doing another action if I want to scavenge in the ruins I need to check to see if I have enough stats if I'm in the right area all sorts of actions I need to do where this sort of behavior needs to be shared and they don't want to write this code over and over again So now We have what we call economic exchanges So this is what our clone method looks like now, you know getting a new clone we check our steps We assert the location is an area clone that wallet pay The price of the clone an unclone gestate in that area This middle thing is an area pay gestate. That's actually a method called on an economic asset I won't go into details, but basically we have a declarative way of asserting all of these things must happen in this order More or less in order for this thing to happen if any of those steps fail it all rolls back We typically don't even hit the database until we get to the end There's a lot more stuff in there such as you know if it fails do this it succeeds But it's a much much simpler way of writing this and now I can share this self is an area clone that self is an area Ruin self is an area bar. I can share all of these behaviors very easily and it makes writing new behaviors for the game trivial So this was the old method. This is the new method You know in fact, we probably want to fire the guy who wrote the old method, but that was me so One of our devs looked at and said hey, that sucks dude and he came up with this and it's a much much nicer much easier way of Controlling the system and this is also a lot easier to read on the right-hand side It brings us to our next thing though. You might be more of concept of God objects if you're not For newer developers an object-oriented program and they often tend to fall into the trap of creating a God object Which is where you're putting in way too much behavior in a particular class that makes a class much harder to maintain It's a frustration and classes should follow something we call the single responsibility principle if you have an invoice class That just represents your invoice and your date and that represents an order which might reference a customer Which might reference the order items. These are all separate classes and stuff like that everything has one and only one Raise on debt if you will and there should only be one reason to change a class That's what we say for the single responsibility principle, but we have problems with this so character purchasing of clone Every time I write a method on the character class. I'm pushing more behavior in the character class So What we had originally was something like this we were gestating this on you know Our clone class trying to pull behavior out of the character class and redistributed to someplace else that it would be The problem was you might remember stuff like this where we're checking if the character is in the right area The character can pay the right price a clone class. You just know how to just stage a new clone from a character That's all it should know how to do So we really shouldn't put all this behavior in the clone class because who's responsible This is an MMORPG your character drives all of the actions your character has a responsibility for all of this and when we try to avoid Pushing everything in the character class what we had was ugly stuff like this So this follows a verb subject objects intact missions has missions for NPC character No one could remember what that meant No one I wrote that I couldn't remember what it meant every time I hit that I would stumble across that is very frustrating Whereas if we go to subject verb object, and we try very hard to keep the subject verb object syntax within our code We have if MPC has missions for character No one is unclear about that assuming they speak English or you know speak it well enough They understand as field languages. This is perfectly clear, but it means pushing the behavior back into the character class So this actually makes our code easier to read than this convoluted syntax how we deal with that Well, I said we don't like to experiment I lied Partial classes, I don't know if you're familiar with them So imagine you have an IDE and your IDE you're designing a class in your idea And you have a particular attribute and you annotate that attribute and the IDE says oh I need to make a getter and setter for that attribute so behind the scenes it writes out some extra code Which it then composes into your class at compile time and this extra code is a partial class It might do this for a variety of things a lot of code generators or compilers will use this technique to generate code that you don't see when you write the code but gets composed into your class at compile time and It's not something that humans generally do well until now What I decided to do is this Partial class sounds an awful lot like a roll which only gets applied to one class So we have our roll class and now for your partial class character clone We can purchase a clone. We've got our latest clone respawn. We have our decant time All of these are available in the partial class in our character class. We apply a Set of partial classes. These are single-use roles not designed to be used anywhere else and So you can see you open up your character class and you can see it does clone inventory missions movement There's actually a lot of other partial classes that we have because this game is extremely complex So what we've done is we've taken the different responsibilities of the character and We have broken this down into partial classes. We've logically grouped them and it turns out maintenance on this was trivial It was really easy to do Because we were using roles This was giving us some of the benefits of static code that I won't go into right now But it really simplified our code and we were surprised It was so much easier to maintain and we're waiting for this to shoot us in the foot at some point, but it hasn't So we're very pleased with that Thank you, so let's move on to the next thing though item design This is the part where it really gets frustrating because when you're building a business system It's much easier to control the logical design of the things that you're building So imagine You're trying to represent something closer to the real world and you have armor a combat suit It acts as armor, but it also much fire back at the opponent for you so it can act as a weapon or Maybe you get hurt in combat so it tries to patch you up So it acts as a medkit where you get scared in combat and it tries to whisper nice things to you to build your morale So it acts as a psychiatrist Single responsibility my ass Pardon my language How does that work? How do you model something like that? So oh, that's not just picture about medkit items. Sorry. That shouldn't be there In any component system It is a pattern very commonly used in regular games And basically an entity is what we might think of as an object combat suit handgun medkit, etc. Components different things it can do it that it's a weapon it can act as armor It does movement entities have zero or more components So an entity might be as simple as you know having a name and a weight everything has a name and a weight So that doesn't do anything else, but these are flavor items are available in the game entities are data They are not behavior. These aren't the way we typically think about this So how they actually work is in a typical game loop while the game is running we get our user input We update the state we drive What does update state look like? So maybe it's a game about animals running around in the forest first The animals tend to hide from danger to be safe once they make sure they're safe They forage for food then they move about then they attack enemies. What is courage for food look like? For entity in entities we iterate over our list of entities and if is animal entity search for food entity notice entity You're not calling a method on the entity You inspect the data inside of the entity object to find out if it can behave like an animal And then you call this method or you call this function passing it the entity is an argument So the entities don't have behavior. They simply have state But we're the web we don't actually have a game loop So iterating over all those entities can be extremely expensive in games if you have millions of entities So they have all sorts of tricks for filtering stuff We actually have something simpler because we don't have a game loop So we just check the set of objects that we're interacting with at the time that we you click on a thing and It complex behaviors become really simple. So let me give you a concrete example So we don't do it this way anymore, but this is how we initially did it and it's simpler to understand So implementing ECS with a view We select the first thing is all the items all the data that we need to select for a thing Which everything has names like weight, etc We select our armor component our mod component a mod is like a bionic or genetic mod that you go to a sick Bay and get installed inside your body You know weapon component and then we do a left outer join on the tables containing that data Why do we do a left outer join because of the data is not there we get? Null results on deaf and pearl and then we have predicate methods We can see if it's a if it's armor to find out if the armor ID is defined Is it a weapon is the weapon ID defined? And you might remember those economic steps we talked about earlier Well, it doesn't have to just be the character as that first argument inside of a step here We're going to install a mod in a sick day So location we check that we're unconfined. You don't want to be in the brig or sick confined to the sick day Then bless you then we check that we're in the area sick day We checked that our wall has enough money and then inventory The inventory object for this we're going to install the mod or attempt to do so and the method Down here we get to our predicate method if item is mod and remember We're just checking to see if the mod ID is defined out of the left outer join That's how we can have rich Incredibly incredibly complex behavior on objects very simply It's not single responsibility. It does something a lot different from what we see from additional object-oriented programming But it works out really nicely So when developers start on this project most of them gush over it Most not all and they're really surprised. It's very very clean and beautiful for production code It's very easy to work on I'm very happy about that if you go out to tau station dot space You can see the web page and there's a blog link there or you can sign up for the newsletter if you want to and That'll give you a little bit more information about it We actually haven't sent anything sent anything on the newsletter yet because we don't want to spam folks That'll make you eligible for the alpha if you want to play You can also follow us at tau station on Twitter. That's interesting because we're not just talking about the game We're also sharing the latest science news the latest science fiction news If you're a science and science fiction buff following this feed is just awesome. It's a lot of fun And as usual we have two choices now I can a take questions or B I have some bonus slides about some of the science involved Every time I love it So is anyone here read the series the expanse or watch the television series? Okay, cool. So a lot of times I see people Complaining about one of the initial ships in the game called the kentaburi is an ice hauler going out to the rings of Saturn mining ice bringing it back Waters ridiculous. That's kind of a joke. Why would you have ice mining? The average person in the Western world consumes a cubic meter of water every two to three days And you think no, I don't Know we're close to a cubic meter of water Yeah, you drink your flush you bathe you mop the floors watch your dishes watering the lawn you go through a lot of water Huge amount of water and people don't think about it So just keeping the mass simple. That's about a hundred cubic month a meters of water per person per year But a cubic meter of water. That's a thousand kilograms or a ton Each of you goes through a hundred thousand kilograms of water a year. So 10 people. That's a million kilograms We're supposed to have 80 people in this room. You're going through eight million kilograms of water per year Just the people in this room. That's a lot of water How's this actually going to work on a space station? So let's assume we have a hundred thousand people on a space station Uh, a hundred that's going to be a hundred billion kilograms of water a year If we were to hit 99 efficiency at recycling and that ain't gonna happen. I don't care how far in the future you get It's not going to happen. That's going to be a hundred million kilograms of water in a case you're wondering Largest animal on earth right now is a blue whale. That's about 700 blue whales worth of water That's a lot and that's heavy For comparison by the way, the international space station is 70 percent efficient at recycling They were hoping to be 85 percent efficient But they found a lot of the water they had was too acidic so they couldn't get there In the future though, you're going to have a lot more space stations docking and undocking or ships docking and undocking at space stations The airlocks are going to open and close a lot more often A lot of the water is going to be used as reaction mass and maneuvering thrusters You will not hit 99 efficiency, but you're going to need a lot of water So just for that small population that's a small town a hundred million kilograms of water That's assuming Beautiful beautiful efficiency recycling so ice mining is going to be a major industry in outer space And as a result Uh, it is something which we're going to be bringing to the game later on. It's not going to be in the alpha But it's it's an important thing and we do want to pay attention to the science Calculate the orbital velocity of something Um, I got this formula memorized at this point what you do to calculate the orbital velocity of a satellite This is the simple version, but it's fairly accurate You take the gravitational constant Multiply that by the mass of the thing you're orbiting around and then the radius is a distance of the item from the center of that mass No, you don't actually have to consider the mass of the item that's doing the orbiting You just need the central mass and for tau station the primary space station in the first space station in the game It's orbiting around mars So we take the massive bars multiply it by the gravitational constant It's orbiting at a radius of about 11 000 kilometers We multiply it by a thousand because uh gravitational constants measured in meters That gets us the velocity of the space station and that turns out to be extremely important for our games By comparison, uh, so the international space station orbital radius almost 7 000 kilometers The altitude is considerably different international space stations 400 kilometers versus almost 8 000 tau station moves at 1.9 kilometers per second Which is actually really slow because the international space station 7.66 kilometers per second And takes about an hour and a half to orbit tau station takes almost 10 hours to orbit mars What that allows us to do knowing this information Our get radians method up there. We have our elapsed time, which is the epic Our current epic minus the epic of the game that tells us our lap time in seconds We get the orbit time of the particular space station. We do a mod Basically, you divide it you just take the remainder that gets rid of all the proceeding orbits Do a mod to figure out how many seconds in the current orbit you are and simple math gets you the radians And then for your x and your y you pass in whatever date time you need You get the radians and you just use simple trigonometry to determine the current position of space station What that means is the cron job that i had written To update the position of space stations has been deleted because now we can Determine the position of the space station at any time on the fly and space station data is now immutable Which solves a number of problems we had in the game We do assume station orbits are thank you are circular keeps things simpler, but it's fairly accurate And this is important because we can now calculate the distance between two space stations again simple trig Because you want to travel a lot and you need to know the travel time between the different stations If you go to the port and you just refresh that page a few times You'll see the price changing. You'll see the travel time changing because we actually again stuff that we pay attention to even The information time sending an email to someone else We're trying to calculate how far away they are so that the email gets delayed. It's not going to be instant because this is space So that's uh the basics of it. I hope you enjoyed it. Does anyone have any questions? Yes To sustain What kind of database system? Yes, because I said that that kind of joins you have a lot of squares like that Okay, so behind so behind the scenes. Uh, how do we actually handle that? There's a lot of drawings. Yes, it's very expensive Um, so there's a couple of things we do first of all it's post-resql underneath We strive very hard to have a properly normalized database as much as possible So that we don't have to worry about the problems with that and because the core item information doesn't have to change You can cash that So all of that is trivial to cash Now when you get the item and it gets inserted into your inventory Then it's no longer as easily cashable because you know the item might get damaged or might get reduced But primarily it's just stuff that we can easily cash using chai and we use redis as the back end for that Which also means if that goes down we can still go back to the database and fetch it So you would lose some performance, but that's why we like immutable data as much as possible. It makes caching easier Any other questions Yes Not at the present time It is something that I had looked at from time to time, but no So most of the time for the speed at which their ships travel and behind the scenes we actually We were actually Considering like the g-force you would have when you were traveling Relativity did not make a difference in most of those calculations. So we decided to not use that That may change in the future Are there any other questions? Yes That's actually an excellent question So I started this project back in 2010 and then got it dropped because I had a book deal And we had a brand new baby and then we moved to another country and those kind of interfered with things But when I first started I was thinking well, maybe I should try something different Like you know rails or something like that and then I realized actually I want to make a commercial product I don't want to take risk on this So it was a decision from day one that I want to stick with something that I know works That I'm not going to be stuck wondering how I do this particular thing for a long time because I didn't realize that Have a large team behind me. So pearl works It's rock solid. It's battle tested it's been around for 25 years And I don't have to worry about whether or not I can do what I need to do. It's going to do it But it hasn't been battle tested with the large scale teams You're not familiar with lacuna expanse there's a so booking.com is the Fourth largest e-commerce site in the world the entire back end almost the entire back end is written in pearl Curl handles large loads It's there's nothing unusual about that most of the performance issues you have with stuff like that are In your network or your database iso stuff like that. It's typically not cpu bound. So I'm not worried about pearl with that Any other questions Yes, how do you manage to sync very different user actions? So you have a user that makes a change and I need them and that affect a new user How do you manage that the problems with race condition? um, the problems with race conditions there most of that is the How do I manage the user actions to avoid race conditions and stuff like that is what he's asking about making sure they're synchronized So some of it is simpler because you're in a different room and if i'm impacting a thing It's not going to impact you other items. It is We check to see everything that can be done And then we have a transaction in as high loop as possible so that we don't we try to avoid rummaging around in the database a whole bunch and you know Do a do a lock beforehand and then do a whole bunch of stuff We try and keep those transaction times as small as possible We did actually find a case where we had some locking in an unfortunate position And that's part of the reason why I wrote the box in golang to really smash it back to catch issues like that So in this case, it's finding out what actually has a real impact in solving it