036: Game UI in Go with EbitenUI maintainer Mark Carpenter
Hey there. I'm Lemick Saint Pierre and you're listening to Go Bad Gass. Today I talk with Mark Carpenter and we, discuss about game in Go. And it is library, Evoton UI. Hello, Gophers.
Dominic:This is Dominic Senthier. And, you know, I have a special guest today. To be completely frank I was going to, to do a solo episode on Epitin very recently. And I saw a comment on Reddit, and I have Mark Carpenter with me today. And thank you very much for accepting this invitation, Mark.
Mark:Oh, yeah. You're welcome. I'm excited to talk about the library.
Dominic:Oh, absolutely. So so Mark is the author and man maintainer of the, you know, a bit in UI. And, I I will I will start by just asking you if you can, you know, present yourself a little bit, give us some background. I like to ask, my guests to, you know, to have some bias a little bit towards go. But, you know, it's it's not it's not necessary.
Dominic:I I think I, I think we all we all like to, to hear a little bit about you.
Mark:Alright. Yeah. Sure. So hello. Name's Mark.
Mark:I've been a software developer for about 20 years now, and, most of that's actually been in Java. And I've never actually worked in Go professionally, so that's probably a little different from some of your other guests. But I became pretty much an enthusiast because I wanted to learn the language. I saw it when it was originally posted, and I've always wanted to learn how to use it, so I made an effort to learn how to use it. So along the way, I've take taken ownership of Ebitten UI.
Mark:I've built a couple tools for game development in in the language and, like, some simple blog software stuff, you know, the standard, like, learning the language kind of stuff. So
Dominic:Yeah. Yeah. So nice. So so you have you have worked all your all your career in in Java. Is that is that right?
Mark:That's correct. Well well,
Dominic:mostly time for Java.
Mark:Yeah. Right? I actually started off as a c sharp developer for, like, a year. I got hired on at this job, to, be a c sharp developer. And then, like, the day I started, they're like, oh, no.
Mark:We're a Java shop now. Learn Java. And I've been there ever since.
Dominic:I'm I'm curious to, to hear, and, you know, even if you only add 1 year at at C Sharp, what what is what is your comparison? What what is your thought? Because, I, you know, I'm I'm coming from the the other way around. And I'm also, you know, near, 20 years, a little bit than 20 years. So we we we seems to be very similar.
Dominic:But, myself, I I was on the Microsoft stack at the at the beginning and always kept far from Java. For for you know no really particular good reason and things like that. It's it's it you know it just never really happened. But I'm curious to hear how how was that transition, went for you?
Mark:You know, thankfully, it was like a small start up shop, so there wasn't a lot of expectations. It actually went really well. The, c sharp and Java, the syntax was very similar. The main differences was learning the libraries and some of the nuances around Java. So, I mean, it was actually I thought it was easier to go from C Sharp to Java than to pick up Go from Java.
Dominic:Interesting. Interesting. Why is that? The is it is it because of the object orientation, for example, in in those languages?
Mark:It is. And the syntax is similar. The general structure of the applications is very similar. Like and you actually have similar libraries as well. Like, there's a hibernate and in hibernate for doing data models and stuff like that.
Mark:Frankly, it's just really similar. I do kinda miss c sharp sometimes because I thought the, UI integration with c sharp was better, just a lot better than with Java. But, I mean, that's part of the .net running on Windows machines, they can do that, whereas Java is supposed to be able to run on anything. And when they try to create swing, it was just kind of a giant mess.
Dominic:Right. Okay. So when when you said UI UI, you mean, building, you know, GUI application like desktop, Windows form, and WPF, QA. Right.
Mark:Exactly.
Dominic:Yeah. Yeah. I I'm I'm I'm also missing sometimes c sharp. To be completely frank here, for me the the part that I I really enjoy was when they introduced LinQ at some point. So I I always worked in in, you know, database heavy or data heavy companies and whatnot.
Dominic:And, but
Mark:I get that link. It's or link queue. Not really sure of the proper way to pronounce it.
Dominic:Well, yeah, man. Maybe it's link. Yeah.
Mark:It's fantastic. It's really well designed, and I think it I've always thought it worked really well. Over the years, Java has been incorporating more and more stuff like that with its stream APIs, which is nice, but it it never quite felt as integrated as, Link did.
Dominic:Yeah. Yeah. Yeah. I I I believe yeah. I believe that's also why I was, a little bit attracted in Elixir for for line of business application as well.
Dominic:Because they in my opinion, they their ORM is is it seems to be based a little bit on link if I if I can say that. But, you know, I'm Yeah. I I don't have a huge experience in Elixir in production, but I always, enjoy their, the way that, you know, the data is is is flowing in in the in there. Yes. Let's jump.
Dominic:Yeah. We I think I think we have to talk a little bit more on c sharp and and Java. That's fine. Let's let's talk about, a bit of UI. So how how would you describe the library itself?
Mark:So the library is a user interface for video games. It's not built to be a generic user interface, graphical user interface, front end application. That's not the use case for Ebit and UI. It is built completely to be a UI layer on top of Ebitenjin or Ebiten. I think it's Ebitenjin now to be on top of that, system for building games.
Mark:So because of that, it has some, like, different design choices than something like, fine or whales, which are 2 of the other really well known UI systems for, Go.
Dominic:I'm interesting yeah. I'm interested to to unpack that a lot because to be completely frank, when when I saw your your posts, on on Reddit, I tried the library and the first thing that came to mind was, wow. This thing seems to be the, probably the easiest way to build desktop application with go. That that was and I'm I'm currently do doing a small, a small game with, with my younger, kid. You know, it's it's a known fact that I'm a blind person and wow a blind person is is programming a game.
Dominic:Yeah. I'm not I'm not doing any images and whatnot. So my kid is is, is very attracted by, pixel art these days and things like that. So I'm just I'm just programming in Go, Aveda. When I saw, you know, the results, you know, buttons and and, I I and I know that fine and wells are are the the go to thing here.
Dominic:But I have tried them. And to be honest, I'm I'm surprised that that you're saying that it's not the use case. Could it could it be?
Mark:So
Dominic:an an alternative or not?
Mark:It could be. It it absolutely could be. That's not the main use case for it. It's primarily designed, like I said, to be a UI for games, but it absolutely could be if that was your intention, if you wanted to build it like that. And I may be a little biased, but I actually do think even UI is easier to use than the other 2.
Mark:Like, with Wales, that one is essentially just a browser packaged into an EXE. So you get a the standard stack of a Go server and, like, some sort of HTML front end, like Vue or something like that. So you're still building a full stack application and it's not like just a GUI app. Yeah. And then and then find, find's really neat, but it does absolutely take over your your system.
Mark:Like, you do a find dot run, to run the system, it takes over everything. Even UI tries not to do that, It tries to be as easy as possible, again, because it's typically used as an overlay on something else.
Dominic:Right. And I I haven't looked much at the code. So again, I have just, you know, I've just run the demo. Mhmm. Is it, is it like using the same same kind of, construct as the as a game?
Dominic:Like, a bit in a bit in gin, I don't know how to to say
Mark:that. Right?
Dominic:But is it is it like you you you kind of, have a a drawing and update function? Is it is it like that for the the the GUI as
Mark:well? It is. So it ties into the, update function. Basically, you call uidot update and a uidot draw inside the draw method from, the bin engine. And, that's where the system's doing its work to draw the UI onto the screen or to update and capture, like, mouse clicks and keyboard inputs, things like that.
Dominic:Yeah. Yeah. That that that sounds pretty sexy to me compared to to find. Like you said, find find seems to to take over the entire well, which is which is normal. It takes like the the main thread if I if if we can say that.
Dominic:But Yeah. What what I like so far because, returning to my small small project, We we started with, with Pygame because I I thought that my kid was going to to write some code at some point. But, it turns out that, you know, it's it's not like that. It's just images and and graphics and and things like that. So I I I said, you know, it's a good time to try this this ibutan thing.
Dominic:And I really appreciate the the simplicity of having, you know, to function the the draw and update with which lots of games are like that but now you are talking about the full a full GUI application that you you just you just create a struct and you attach 2 2 function like that. And you can start to compose some pretty nice, I I don't know. You know, maybe I I would I would even say, like, decouple the logic in your in your GUI, which which sounds interesting to me.
Mark:Yeah. And, actually, I'm doing that in my own games. So I separate out, like, my I can't create custom widgets based off of the existing ones that are provided by the library, to build out my game. And it's all composed inside its own struct with its own methods, and I can just call that. Like, it's very composable, if that makes sense.
Dominic:Yeah. Yeah. Absolutely. So what what is your game actually? And and, you know, can you can you tell a little bit how you, you know, you you started, this this UI kit, actually?
Dominic:What happened there?
Mark:Alright. Little bit of a long story, but I can start from the beginning if you want.
Dominic:Sure.
Mark:Alright. So I started learning Go, and I did I mentioned it earlier. I did a dumb, like, blog kinda app thing just to test login and all that kind of stuff and working through networking with Go. And as I was working through it, I'm like, okay, this project's kinda boring. And I decided, hey, why don't I make a game?
Mark:And it's like, hey, I love MMOs, that's my favorite genre of game, so let's try to start with that. I know it was a project I didn't think would ever have a finish, and that's actually one of the biggest reasons why I chose it, is because it's something I could continually work on and use to improve my skills with language and with the the libraries. So I chose that, and I built the the back end, the back end servers, because there's actually 4 servers that support it, talking to each other, with, NATS, if you're gonna support it, talking to each other with NATS, if you've heard of that library.
Dominic:Yeah.
Mark:So I built all that. And for the front end, I was using Godot, and it was nice. It actually worked really well, but the networking section of Godot is challenging if you wanna have your own custom back end. Mhmm. It had the ability to do, like, web sockets for network communications, but if I wanted to use, like, something like ENET, where I could use the UDP communication back and forth.
Mark:And while I was able to hack it together, it was just not great. And then they released a newer version of Godot about a year ago, a year and a half ago, something like that. And when they did, it completely broke all my tile maps and everything I had built, like it just completely destroyed my game. And at that point, I just kinda got frustrated and said, I'm done with Godot, and started looking for other frameworks. And I really wanted to stick in with, with Go because the back end was in Go and I thought there'd be a lot of synergy with the front end and back end both being in the same language.
Mark:So, started looking around, found EBIT engine and tested it out. I'm like, okay, yeah, this works great. I can do tile maps. I can do all the physics and all the standard stuff you wanna do. But when I started looking at building a UI on top of it, because it's an MMO, it has chat boxes, it has settings menus, that kind of stuff, right?
Dominic:Yep.
Mark:I couldn't find a good library for it That would just do the things I needed it to do. And then eventually, I actually stumbled on the original version of Ebit and UI. So I'm not the original author of Ebit and UI. However, the original version was deprecated 3 years ago, about a year and a half before I found it. The original author kind of abandoned it and stopped working in Go, or with Ebitten.
Mark:And so I started playing with it, I realized, okay, this actually has a really nice framework. Like half the stuff doesn't work, but it has a really nice framework and I like working with it. So I started working on my game and building my game and my UI in this library. And I realized I was making a lot of really nice changes, to make things work as you would expect them to work and adding new widgets, etcetera. And I wanted to push that back up to the main line, but it was deprecated.
Mark:So, I really didn't wanna keep a fork, but I also thought, there's no other real good UI libraries, in my opinion, for Ubuntu. And I don't want the fork to be the main one, so I reached out to the original author. And after a little bit of back and forth, he agreed to give the keys to the kingdom, essentially. He passed ownership of Ebay and UI over to me, and I've been maintaining it ever since.
Dominic:Yeah. That's that's a great story, to be frank. I mean, this is, this is this is very interesting. So but there's there's there's a lot of things I I want to unpack in here. Alright.
Dominic:Oh, yeah. Oh, yeah. So first of all, well, first of all, yeah, the the story with Godot is pretty sad. But I'm I'm curious to to know why why you choose Go for your back end server for this MMO? What what was the reasoning there?
Mark:Actually, really good reasoning is Go is very good at networking. I mean, it's built to handle a lot of network interactions. Like, that's its primary use case, and it worked very well for this. And, doing a lot of threading and things like that, which align really well with building a server in the back end. And, frankly, I just want it to.
Mark:Like, I like working with Go, and
Dominic:Yeah.
Mark:This was like a project that seemed like a lot of fun to work on in Go.
Dominic:How were you testing your server, you know, while you were probably not having any client to, to to to play the game in in a sense, were were you were you using a lot of unit testing and whatnot? You know, what what what was the development cycle was like?
Mark:So, actually, I built them hand in hand, the front end and the back end hand in hand. So I built the original the networking, scaffolding, basically, to do the the handshakes and create the connections and stuff. Like, when I was doing that, I did it on the client and the back end at the same time. So that that made it actually really easy to test, because I could just run the front end and did it connect. Yeah.
Mark:Okay. I'm good. Right? So once I got the the scaffolding done for the networking, I started adding in, essentially, my own personal protocol, using the message pack, library to create these packets of data that I'm sending back and forth. And as I was adding new features to the game, I would add new message types to that to that protocol.
Mark:And, it's set up so that the main server, just essentially takes those messages It keeps the connection with that user, but passes it to a back end using, messaging framework NATS to, send the messages to the appropriate back end servers. Like, so the front server that they connect to, you I can have as many of those as I want, and just scale that horizontally as much as necessary because it's just the front door, basically. I have a data server that connects to our data to the database system that saves off, you know, the user information periodically or or is used to load the information on, you know, startup, that kind of thing. But it's all, orchestrated through that NATS messaging framework I had mentioned earlier.
Dominic:Interesting. Is is the server responsible for, you know, all all the the object in the map and and things like that? So that the positioning of things and and, you know, if if a player is moving to replicate that to other other user, is is it is it is it done directly there? Does does the rendering is done on on the server side?
Mark:No. Well, yes and no. So like I mentioned, the the front end server, the first server, I call it the game server, doesn't handle that. It's actually sending the messages back to the appropriate back end server that's associated with the area they're in. So the world's chunked into multiple different chunks, essentially.
Mark:And each of those chunks is responsible for the information about the characters and creatures and stuff in that. I'm gonna use the nomenclature zone. They're in that specific zone. Then that zone server is responsible for tracking all that information and keeping track of all that.
Dominic:Mhmm.
Mark:So I run, like, 4 or 5 of the exact same code base. The only difference is a data file that I associate with it, which has the map information for collision checking and, you know, n p c information. Speaking of maps and n p c information, I actually built a live or application in Go that does all that for me, allows me to, you know, drag and drop my NPCs into the right spots and set up spawning zones and loop tables and all of that inside this highly customizable app that it it's all like, the entire back end's written in Go. Front end's in view. I'm I'm actually really proud of it.
Dominic:Nice. Yeah. Sounds, sounds pretty cool. I mean, so so the collision detection is is done on the server side, you you are saying then?
Mark:Yes. I'm doing some some collision detection on the server side. It's kind of more high level. I'm not as fine grained as I am on the client. So it it's doing, like, reality checks.
Mark:Like, you can't go this far off the map. Right. Right. Eventually, depending on how things go, I might add more detailed collision detection on the back end. But for right now, most of it is on the most of it's on the front end.
Mark:Like, right now, the the major, like, detection I'm doing for physics on the back end is, are they actually close enough to the MPC to hit them? That kind of thing or to talk to this in to this merchant.
Dominic:That's great. So when when you say that the front end is in view, so I thought it was it was going to be in in Hibbetton because after after Oh,
Mark:I'm sorry. That that library or that application I built to build the, like, build the map and build the world, that one is that one is in view.
Dominic:Oh, okay. Got it. Got it. Yeah. Okay.
Dominic:So it's like a it's like a world builder that that you have Yeah.
Mark:Exactly.
Dominic:To create your file that you drop on on the server at the end of the day, I guess.
Mark:Exactly.
Dominic:Oh, interesting. Interesting. Okay. So so Godot, you know, it it it's crew your your your, your tile and and your images and and whatnot. So you decide at some point, well, let's try to see if there's something else.
Dominic:Right? And and and because of your server is written in Go, you you you tend to to go with Ableton. But, have you have you tried anything else? You know, I I know that Raylib is get gets a lot of, of mention these days and and even even in Go. So, I mean, have you have you tried that?
Mark:So I tried it a little bit when I started working on my, my MMO's front end. But the reason I leaned away from it is because it's a c it's a c library that just has bindings in Go. Yeah. So it's it's not built specifically for Go. And that was honestly, that was a concern for me.
Mark:My concern was, hey, what if the person maintaining these bindings either gets behind or gets deprecated and, hey, there's this new feature that was just recently added, but the bindings haven't been updated and, who knows when the person's gonna be able to do it. So it was just I had concerns about using using that because of those reasons, because it is a binding directly to a c library. Whereas, he bitten is built for go and runs in go. And recently, they've been working on something called Pure Go, where they're getting rid of their, their c bindings and doing everything directly in Go, which is super interesting. I think it's actually set up that way in Windows right now, and they're working on other systems to enable that.
Dominic:That's nice. Yeah. The big that that's also you know, it match a little bit my experience. So I'm I'm developing in, I'm also using, Windows for, my screen reader and whatnot. But I'm I'm always inside the the sub WSL.
Dominic:And Right. I I kind of, I kind of I'm able to, to set the the Gortch and the Go Arch and the Go, Go OS to Windows. And now I can build the game and it's running natively on Windows directly. So I don't I don't need to, to have anything to to run it. So I I find I find that very very great.
Dominic:So that that that was a a little bit, a concern for me with Raylib and and yeah. The fact that it's, you know the the there's a seed there. Seed dependencies that it's it's not as easy to build. Especially cross platform like that, to be frank. So
Mark:Yeah. I actually haven't gotten my my front end to run cross platform yet. My back end runs in Linux or Windows or whatever. It doesn't care. But my front end is running in Windows, and I've been trying to expose it to other operating systems, but I've had problems getting the build to work properly because of the some of the c go dependencies I have from, ENET.
Mark:I've been using the ENET library for networking.
Dominic:Sure.
Mark:And because because it's a, you know, a Seagull connectivity thing, I'm having issues getting it to build properly, and I kinda just gave up because it wasn't a high priority to look at later. But, at some point, I'm probably gonna get rid of ENET as well because of the same reason why I chose, ebiten is because I don't like having those c go con like, those connections. It it causes build problems and things aren't updated at the same time because they're, you know, just bindings. They're not the actual library.
Dominic:Yeah.
Mark:So
Dominic:Yeah. Yeah. I hear you on that. Alright. So at at some point, you you have your your game rewritten.
Dominic:Were you very far away with your good old version? How much time it took you to to rewrite that to, to a bit in?
Mark:So it it took me a little longer than I anticipated. I mean, in the end, it took me about 6 months. But part part of that was because I had to rewrite a significant portion of EBIT and UI to, support some of the features I needed. Things like, there's a window widget, which is what it sounds like. It's a widget that you can drag and drop across the screen and have other widgets inside it.
Mark:So like a pop up window, basically. Mhmm. And when, like, I originally took over the library and started working on it, you couldn't have other, like, input widgets with within it. Like, it just didn't work. And you also couldn't drag and drop it either or resize it.
Mark:It's like, no. That was implemented. Like, it it had, like, the base framework of the idea of what a window was, but not the actual implementation. And that was kind of what happened with a lot of the the widgets within the library. So I ended up having to do a lot of that cleanup before I could implement it in my game.
Mark:So I would implement what I could in the the game's client. And then when I got to a point where there's some UI elements I needed to add, I would go switch over to EBIT and UI to work on that to get that enabled and then, you know, deploy that, do a release, and go over back to my game and pick that in and start utilizing it. So it took a little time to get EbinUI to a place where I think it's in a really functional state. Obviously, there's, you know, more work to be done, but I think it's in a very nice state at this point, and I've had no problems integrating and finishing catching up to where my client originally was.
Dominic:Yeah. Were you having the, the total ownership of the project at this moment?
Mark:Yes.
Dominic:Oh, interesting. Okay. I I guess that's yeah. Yeah. Totally.
Mark:Nice thing though, while I was doing this, I actually did get people, giving, pull requests along the way. So people have been using it and, like, they like it enough. They're like, hey, let's add this to it. It's like, alright. Perfect.
Mark:So I've actually had some pretty good interaction with the with the users of the library. On my Discord, they've been giving really good feedback and helping out with PRs here and there.
Dominic:So was the Discord, came with, with the ownership of the repo as well, or you started that from scratch?
Mark:I started that one from scratch. Yeah.
Dominic:Oh, that's good. I mean,
Mark:the only thing what came with the library when I took ownership was the main repo and then a repo for the docs. So there was a basic docs page that, was put together. I believe it only had 1 page at that point, maybe 2, but has since been enhanced quite a bit. But that was it. It was just those 2 repos and then nothing else.
Mark:So since then, I've just kinda been trying to build it out, and sharing it with the world and sharing it with those in, the Discord as well so they they know it exists, and they can use it if they want.
Dominic:Well yeah. Yeah. Totally. I mean, this is this is great because, I mean, all games needs need some UI at some point.
Mark:Yeah. Most of them do. I mean, I have definitely seen people just implement the very basics on their own, like basic buttons and stuff. I actually kinda feel bad for them because it's like that it's almost a waste of time, man. You could get that very, very cheaply if you just use this library.
Dominic:Oh, totally.
Mark:Yeah. But I get it. A lot of people come to a a tool like eBiden because they want to build a lot of themselves.
Dominic:Yeah.
Mark:And that's part of the reason I came to the language and the the library.
Dominic:Yeah. It's a good learning curve, to be to be frank, to start from scratch, you know, compared to having to learn a framework or or any kind of of tool. I mean, it's it's nice to understand what's going on. I think I think, I think EBITDA is is that that type of, we can compare that to any kind of frameworks on on the web side. It's it's it's nice on on go that, you know, you still you still can go very, I would say, very deep and understanding, you know, a little bit of the HTTP stack and whatnot there.
Mark:Definitely. I will say I really I really appreciate what they've done with Ebit, and it's just so simple to use, and it makes so much sense when, when you look through its documents. Like, building this UI library is very easy because of the work that, they've done on their library.
Dominic:Yeah. Yeah. I I I also think that. I I've I've seen it. It was a long time ago.
Dominic:It was sold like it was talking about the NES system, like, 8 bit game like the NES and things like that.
Mark:Right.
Dominic:So, yeah, I I I seen it, and I was like, yeah. I I I don't know. But but it's it's way more than that. I mean, it's, it yeah. For for 2 d games, I mean, it it just works.
Mark:It really is. I mean, any kind of 2 d game works really well with it. I've seen, like, some isometric stuff. I've seen just straight 2 d, and I've seen a couple other things. Someone's built, like, a rudimentary 3 d engine, kinda like a Doom kind of engine in it, which is kinda neat.
Mark:And right? And, I recently saw someone's building a, like, a 3 d mech game in the language as well. If you look in their show and tell forum, it's on there. It looks really cool.
Dominic:Wow. Yeah. Yeah. That's impressive to be frank. And it it's very simple.
Dominic:So if I I mean, if if you're listening to that and you you you don't really know it and you you you like to, I don't know, to write some small games and whatnot. It's it's a great way to start, I I would admit. You know, Pygame is is nice as well. I mean, don't don't get me wrong, but you you still you still have a lot to, to read and things like that. But I bet I bet it is just simple.
Mark:Yes. And I tried to make the Ybitten UI simple too. I've done a lot of things recently. So people come into the library, and a lot of them are newer developers and don't really know how to read code from other libraries and stuff like that, don't really want to. So I've done a lot of things to try to make the usage of the library simpler.
Mark:So there are demo widgets for or demos for every single widget, And you can actually, connect to them on the web and see every single widget we have as a WASM embedded into your web page application, for every single widget, which is kinda nice. And then you can look at the source code for each of the widgets with comments to explain what the different functionality does. So that actually took a whole lot of time to get that working and to get that, put together. But, I'm really happy that that's out there now.
Dominic:Yeah. It's it's really helpful to, to see a demo like that for sure because you, you know, you you can just see what what what you can do with it. To be frank, the the the WASM exporting of of the Ybitten is really nice. I mean, I have you have you have any issues to to output your the library? Was there any any kind of of, you know, tricks that you needed to change or any any any problem that you had?
Mark:Actually, yeah. There there's a really big pain to get this working on, WASM for input dialogue. So anything where you type into the screen, it didn't really work on mobile. So it worked fine on desktop as it was. But if you pulled it up on a mobile, browser, it wouldn't work because the the the keyboard wouldn't pop open.
Mark:So I actually spent, a week, week and a half working on it to get the get the, the the silly keyboard to pop open when you click inside the, the text box. And that was that was challenging. I had to do some of the JavaScript interop stuff with with Go to get it to actually call the right methods to pop it open, and then do the interaction to say, when they hit this button, copy it from, like, this hidden input widget into the actual widget on the screen and back and forth and dealing with, the fact that you can move the caret in different places and making sure that the caret position was aligned properly so that if you hit backspace, it would actually backspace the right character. Right.
Dominic:That that's does not sound fun at all.
Mark:That that was a challenge. I think that's actually the biggest challenge I've dealt with with this library was getting that to work.
Dominic:Nice. And other than that, I mean, it it it looks exactly the same on, I guess, Linux, Windows, and Mac, probably.
Mark:It does.
Dominic:Yeah.
Mark:So it's kinda neat how it works. If you if you're good for me to go into that a little bit.
Dominic:Yeah. Sure.
Mark:Okay. Cool. Yeah. So, basically, what it does is it has an update loop where it's going through and capturing your mouse clicks, keyboards, interactions, and then it's reacting to that on the draw loop. So in the draw loop, all it's doing is just drawing pictures to the screen, which is how eBitten is put together.
Mark:So it is kind of a layered approach. You have this image, and it's using all that information and the setup that you did to position your widgets where you want them on the screen, and it's just straight up drawing them onto the screen. So the draw is actually really simple, it's take this image, draw it for these dimensions, and move on to the next one. It's kinda nice. I I really like working with it.
Dominic:Oh, yeah. Absolutely. So it's it's the same for all the widget inside inside of there. So let let's, is there any drop down? So for instance, when is the library, I guess, is is is, you know, handling when when there's a mouse click, and now you are you are drawing the the option beside the drop down or below, I guess.
Mark:Yeah. It it handles combo boxes. It handles right click context menus as well, and drag and drop, those kind of functionality. It's all bait it's all generally built off of that, that window object I mentioned at the very beginning. So it all utilizes that that window to handle all that behind the scenes.
Mark:So with EBIT with EBIT engine, everything is, positioned based off of a container and a layout for that container. So you nest containers to put widgets in the proper places, And that's just generally how it works. Windows, on the other hand, are outside of that process, outside of that container process. So when you add a window to the system, it gets drawn on top of everything else at the very end. So you you draw your UI, then you create a window, and it will draw that at the end to, put it on top of everything else.
Mark:So because of how that window works, like when you right click on something, it's actually just popping open a new window with the, elements that you've, like, requested to be in that window. So in the back end, it's all just a window, but on the front end, it just looks like a combo box or
Dominic:a
Mark:or a tooltip or a context menu.
Dominic:Interesting. So if if someone wants to create their own widget, do do do they have to to start from this window structure? Or
Mark:So they don't have to start with a window. They could start with pretty much anything. There are a few interfaces that are needed to be implemented. But if you inter implement those interfaces, then you can add them to a container. And once it's added to a container, at that point, it'll start being drawn to the system.
Mark:So as long as you implement the interfaces, you're good. Window I like using Window. All the stuff I utilize in my MMO is based off Windows, but it doesn't have to be. A good example, someone wanted a a labeled checkbox. So originally, the UI like, a bit in UI didn't have a label checkbox.
Mark:It just wasn't a widget. You just had the checkbox and you had a label. Someone really, really wanted that capability to have, like, the label, like, if you click on the label, it'll check the check box to have that that tie in. So they created a new widget called the label check box, where it's the the 2 widgets composed together and, some code to tie them in together for, like, the click events and stuff. So that one, they didn't start with a window.
Mark:They just started with I think they started with the checkbox and added label information to it and added the drawing of the label.
Dominic:So so that means that the the the click events event is is accessible to to to to this checkbox itself. So it's it's not only trapped by, you know, with an UI, but it's also available for the user to do whatever they want to do with that?
Mark:Absolutely. So, we have there's a base object called a widget, which has all of the mouse events. So mouse in, mouse out, mouse mouse pressed, mouse released.
Dominic:Nice.
Mark:And you can tie and add as many events event handlers to those as you want. And it's built so that, you can as you're defining the object, you can specify those handlers as you're defining them.
Dominic:Okay. So is is the is that what you were saying with with the with the loop? I guess you are checking for those property in in inside this loop. So you can react, you know what? Okay.
Dominic:This widget is is pressed for example or
Mark:Yes. Yeah. That's exactly it.
Dominic:Okay. That's that's great. So so this widget, structure is probably something that is a good good blank, blank canvas to to start a a completely custom widget, for example.
Mark:Sort of. Every every widget, like, every new widget has a widget. So that's how it's built. So you it has a widget. So it's not extending it, like, you don't just put it into the struct, you, like, have a widget object within the struct.
Dominic:Right. Right. Right.
Mark:But, yes, that is the ideal way to start a new one. There is some documentation on that in the on the web page. It's not the greatest though. Honestly, if someone wanted to create a new widget, my strongest suggestion would be to take a look at either label checkbox or, just a button and Yeah. Take start with that and go from
Dominic:there to add what
Mark:you wanted. So when I was playing with the library, like learning the library in the first place, that's actually how I learned it is because there were 2 widgets I wanted to see if I could implement. And once I was able to implement those 2, I was able like, it convinced me I wanted to continue with the library. So like a progress bar, that seemed to be pretty simple to me. You know, just 2 images, one fills up the other.
Mark:Right?
Dominic:Yeah.
Mark:And it didn't have it. So I'm like, alright. I'll build this. I'll build a progress bar. And, that's pretty much what I did.
Mark:I started with button and ripped out all the button y stuff and added in the what I needed for a progress bar. I just used, that as a starting point.
Dominic:Nice. So I I suppose there there's some probably public function to set the, the the percentage of the progress bar. For for example, if if you are coming from an external, I don't know. If you if you are creating this game and and this progress bar is, I don't know, the the ELT of of, of a character, for example, you need to set the the value from from the game loop.
Mark:Yes. So it it's not actually setting the percentage. It's setting the value. So you set a max value and the current value.
Dominic:Okay. Yeah.
Mark:And then it'll calculate the percentage to draw based off of that.
Dominic:Nice.
Mark:There are some other things along with that. Like, there's a change event. So when that changes, you can capture that event and do something with it. And I've used that in the past to add, like, a a label on top to show the percentage as a number. That's not built into the progress bar because not everyone needs it, and it's easily added.
Mark:You know, you can easily add it yourself if you need it. So that was one of those design decisions I made along the way. Like, I don't wanna make these widgets terribly heavy because then it just kinda makes it more difficult to use in the long run. Like, you don't need to have a like, it doesn't need to have a label. It doesn't really add anything when you can just easily add one yourself if you need it.
Dominic:Right. And how how is that, usable from the, from the caller point of view? So are we passing an inline function, for example, to this, this event or how does the how does the widget call an external function?
Mark:So you can either pass in, an anonymous function to the, the widget as you're creating it, or you can create a function in one of the packages or off of a struct and pass that in. As long as it matches the, signature, it will accept it.
Dominic:Yeah. Nice. Yeah. That that's, that seems to yeah. Returning to our our first, you know, attempt at discussing GUI application with Phine, this this to me feels very good as a desktop GUI way of building things.
Dominic:So I'm I know that you have said that it's probably not meant to be that, but I don't know. To me, it seems to be it seems to be an interesting aspect that maybe it was not meant for that originally, but it could certainly play that role. And be be because the you know, the concept and the the pattern in in how it's built, it's so simple. It's it's just it's respecting the Go philosophy of just, you know, it just works and it it's just simple. There's no there's not much, you know, mental, mental model that I need to build to understand what's going on there.
Dominic:It's just, you know, it's just very very straightforward in my opinion.
Mark:I like to think so. There are definitely a few challenges I've definitely faced along the way that I know some of the users are facing. And there's 2 of them. I'm still trying to figure out the best way to solve them. But, working on it, like, one of the reasons why I say it's mostly for games is because of these two issues.
Mark:So the first one is it doesn't have a default UI, basically. So
Dominic:Yeah.
Mark:It's almost a headless UI system. It it expects you to provide the images for, like, what does what does a window look like? So it at this point, it expects the user to provide those images on on what to draw. So that's a bit challenging for newer developers who are not used to this system. And, it can be a bit of a a roadblock.
Mark:Like we there is a demo application that does have a lot of these UI elements that, people can use, but it's definitely not gonna fit the style of most people's games. It's kind of like a sci fi kind of, UI look. And that's some one of the challenges that I'm trying to deal with now. I've actually started working on, like, a theming system. And the idea is that, instead of having to, like, provide these images on, like, every button you create, you just say, this is what a button looks like.
Mark:These are the images to use for every button in the game. And, it just kinda goes from there. And long term, once that functionality is added, hopefully, the idea is I'll put out a, a new repo of just you EBIT and UI themes that people can add new themes to, and like add a light theme, add a dark theme to the system so that people can just pull in and start utilizing. So hopefully that would help, make the system a little bit easier for people to use and make me feel a lot more comfortable saying it'd be good for a, like, a desktop application.
Dominic:Yeah. Yeah. This sound, this sounds awesome, to be frank. But, you know, I mean, it's it's not terrible to provide. I think you were saying like 9 images.
Dominic:It would say, I mean, at at the end of the day, you are building your own kind of GUI style. So it's it's it's normal that you you need to to provide some,
Mark:I don't
Dominic:know, some design.
Mark:Right. Well, I think something like, you know, fine, they have this the standard, like, system UI kind of look where this library doesn't provide that right now. I mean, we could, but right now, that's just not something that's provided because that's not really the focus of the u of this system. But hopefully, once this whole theming thing is put together, that that is something we could provide in the future.
Dominic:Yeah. Sure.
Mark:The the other thing is there are certain widgets that people tend to expect on front end applications that are not super necessary for games. Things like, you know, grids. A lot of desktop applications shockingly have a lot of grids, and that's just not something that's supported right now. There there's a few other, like, widgets and container types that we don't support yet, which is, you know, like that one, which is why I'm not comfortable saying it's for Right. Desktops.
Mark:It it's not really a competitor with, like, fine or whales at this point.
Dominic:Oh, sure. And I I guess also, you know, the the tree icon and the file file open safe browser, dialogues. Yeah.
Mark:Yeah. Those are the type of things you don't really see in games, and it's not super necessary. And Right. Like, the window widget, while very useful for games, is not terribly useful for a desktop UI. That kind of style, application's gone out of favor a long time ago.
Dominic:Sure. Sure. But I mean, it's yeah. I under I I I hear you, but I I I don't know. Yes.
Dominic:I I will I will I will, of course, integrate integrate it into, into the small game that I'm building. But I I I just I don't know. It it feels good. So far it it seems to be to be nice.
Mark:I mean, it definitely is. And you absolutely can build a front end GUI in it, like, not related to games. It's absolutely something that can be done. It's just going to take a little, extra work of the type most people doing that wouldn't be used to. So, like, providing what your UI is supposed to look like, that kind of thing.
Mark:But if someone wanted to wanted to do that and wanted to build a front end application using this library, absolutely. There's I see no reason why they couldn't at this point.
Dominic:Yeah, sure. And you and you get you get all the all the sounds from, bitten as well. I mean, there's something to do there.
Mark:Yeah. Right?
Dominic:Yeah. I don't know. So any any challenge that that you're facing? Challenges probably with maintaining an open source project? You know, are you looking for contributors?
Dominic:Is it is it is it hard for you to, to get some kind of traction? How is it going?
Mark:So I'm actually getting a lot of traction of people utilizing it. Like, I know some people have released some games utilizing this library, which makes me super happy. But the biggest challenge I'm dealing with is essentially time. I have my own game I'd like to work on. I have that tool I mentioned before, and I'm supporting this library, and there's just a lot to do.
Mark:Yeah. And it's a lot for one person. So the biggest challenge I have is finding the time to do all the things with EBIT and UI that I want to do. And you asked about contributors. Oh, yes.
Mark:I would absolutely love contributors. I contributors are my best friends.
Dominic:Sure. Well, I I I think that EBIT engine will probably gain some traction, especially if you if they continue to what you what you were saying earlier. If they if they remove the the the c Go, dependencies. I mean, this this is our library to build game in Go. The the native one, the one that is pure Go.
Dominic:It's, it's something I'm I'm seeing a lot of of traction with Go, lately. I would say in the last I would, you know, 8 8 to 10 months. There's something going on.
Mark:Yeah. I've noticed that too. There's there's a bit of influx of people. Like, my my own personal Discord's grown quite a bit in the past 6 months as well. You know, I think it's almost doubled in size.
Mark:I mean, it's not huge, but still doubling size is kinda nice. Yep.
Dominic:So so, yes, I I I think that if if if they are getting traction, then, you know, by ricochet, you you will you will receive a lot a lot a lot of of those, of those people that that want to build game, and they will they will need some some UI. And and this library seems to be very, very easy to use.
Mark:I hope so on both counts. Right. All I know is I'm gonna keep working on the library. I I'm working on it for my own game, so there's no point for me to ever stop working on this library. Mean, it will always be maintained.
Dominic:Yeah. That that's pretty nice. I mean, this is, this is probably the the easiest way to to maintain a project if you're using it yourself. What what about your game? I mean, is it is it available?
Dominic:Can can people, if if some curious people want to to see what, what it is, can can they see it?
Mark:So, yes, they can, but it's only a link on my Discord at this point. It's a link to a private itch. Io download. I've I've left it like that because at this point, it's mostly a tech demo. So it I mean, you can log in, you can create your character, pick your character's faces.
Mark:It has, like, an auto patcher, which was also a lot of fun to build in Go, by the way. And, it does all the standard, like, MMO things, but it doesn't, like, have a AI for the NPCs yet. Right. So or it doesn't, like, it doesn't have leveling up yet. But it it does have, like, the animations.
Mark:You can run around. You can see your friends run around. You can talk to them. You can send private messages to them, that kind of stuff. So I really haven't, pushed it out there because I just don't feel like it's in a place where most people would have fun playing it.
Mark:If you wanted to check it out, absolutely. I keep the server running all all the time, just because I think it's neat that it's out there. But, yeah. If anyone did wanna check it out, there is a link at the top of the Discord for the game.
Dominic:Sure. We we will have the your link in the show notes for sure. What what is, Autopatra? I'm sorry. I I don't know that.
Mark:Oh, so it's an it's an application that runs on your system. So you when you start the game, you actually start the auto patcher. And what it's doing is it's checking to see if there's a new version of the of the game or assets. Yeah. If there are, it will prompt you to download them.
Mark:It'll, you know, hit the download button and it will download all the individual pieces, upload the game, and then restart the game using those new assets.
Dominic:So I'm I'm I'm a little bit curious now about about this if you if you allow me a couple of questions. Of course. So when when when a, a user start the game, so actually, are they are they starting the the auto patcher process or they are starting the game and the game start the auto start, the auto patcher? How does it work?
Mark:So when they download the game, they're actually downloading the auto patcher. And then you hit the auto patcher runs. It says, hey. I don't have all the game assets. You hit the download button.
Mark:It will actually download the game and all the assets like the rest of it. So the initial download's actually really small, but everything else, you know, takes a little bit of time, and then it will only update the pieces that have changed since the last time you ran it. Right?
Dominic:Okay. But let's say we are 6 months later. What when I when I launch the game, what am I launching? Am I launching the the auto patcher or the game itself?
Mark:The patcher.
Dominic:Okay. It's always the patcher. So the patcher the auto patcher is responsible to start the game as well.
Mark:Yeah. So the auto patcher right now is handling the making sure the game assets are up to date, and it's also handling the general login. So doing the log the username, password kinda stuff, and confirming that you have a proper token and then passing that on to the actual game process.
Dominic:Is it 2 separate, Go binaries?
Mark:It is.
Dominic:And I guess that you build the Autopatra, with with Evoton UI as well.
Mark:I do.
Dominic:That's cool. That's that's that's cool.
Mark:That's so, actually, that auto patcher was my main motivation, my first motivation to build a text box widget, because that didn't come with a library either, like, the ability to have, like, a paragraph, like, with a scroll bar and stuff.
Dominic:Okay. So you're you're you're showing the, the latest game update and whatnot in there?
Mark:Exactly.
Dominic:Right. That sounds fun. I mean, for for how long have you have you been working on your game?
Mark:So I've spent about, I'll be honest, about 9 months total, working on it. And I haven't had a chance to work on it in, like, 6 months, which is annoying.
Dominic:Yeah.
Mark:Just because, you know, life and working on other libraries and tools and stuff. But, I'd say a total of about 9 months between all the things.
Dominic:Yeah. Yeah. That's, that sounds, pretty pretty much, it's a huge investment. I I see that. You know, it's it's not like I'm building a game, a huge game or what.
Dominic:Just I always wanted to do that. And, yeah. It's fun. I mean, if you if you if you haven't done that, listener here, I mean, I Let's try it. It it's very fun to build a game.
Mark:It really is. And honestly, I chose one of the dumbest games for a solo developer to ever make. Like, when when I chose this, I absolutely knew the chances of me actually completing it were almost nothing.
Dominic:Right.
Mark:But I don't care. That that's the entire reason I picked it in the first place is because I want a a task that I can continually work on and improve and make better and, like, you like, it's a fun hobby for me, essentially. Yeah. So it's another one of those. It will always keep getting updates.
Mark:It may be slow, but it will keep getting updates because it's fun. It's fun for me.
Dominic:Yeah. Yeah. Totally. Alright, Mark. Is there is there anything that I missed?
Dominic:Do you want to, you know, anything that you would like to add before we wrap up?
Mark:Just anyone who, utilizes library, feel free to join my Discord. I'm always happy to help anyone that has any questions. And if there's something you need that's not there, I'm always willing to, look into adding it, that kind of stuff.
Dominic:Yeah. Absolutely. And I and I and I will I will pro I will I will take this occasion to remind everyone that, you know, when you are using a library and you like it, it's very nice just to, you know, you can open any issues. You can talk with the maintainer as a maintainer myself. So, you know, there there's no small cont there there's no small contribution.
Dominic:Just, you know, just reach out and and see if you can help in in any way, and this is, this is very appreciated.
Mark:Oh, yeah. Definitely. Oh, one more thing if you don't mind. There's a really cool repo in, GitHub called awesome ebit engine, and it has a list of, like, all of the game related libraries you could possibly want for working with ebit. It it's amazing.
Mark:I'll I'll send you the link, and hopefully, you can add it to this because I think everyone would like to see it.
Dominic:Oh, yeah. I don't know. I'm I'm not I'm, like, super curious. I was, sudden, myself as well. So, yeah.
Dominic:Send send me the link. We will have that on the show notes. Yeah. So alright, Mark. Thank thank you very much.
Dominic:That was that was really nice. May maybe you you can return in a in a couple of months and then see and see how things are going. I I I find it very interesting to talk about, about game development and go. I mean, this is, this is not a topic I think that, that we are used to, to associate with go. And we, you know, we have we have very great libraries.
Mark:Oh, yeah. Definitely. And there there's more added all the time. So.
Dominic:Yeah, totally. So thank you very much for your time. And, hopefully we can, we can talk later.
Mark:Definitely. It was good talking to you.
Dominic:Alright. Alright. That's it for this week. I would really appreciate if you can talk or share about this podcast. It's it's always helpful.
Dominic:Also, another way to support this show is by purchasing my course. There's always a link in the show notes. So on that, see you next week.
Creators and Guests
![Dominic St-Pierre](https://img.transistor.fm/HCtTIm4fjr-PPNKVTdewmxYFfFJgSQJkWYmXjb1QLug/rs:fill:400:400:1/q:60/aHR0cHM6Ly9pbWct/dXBsb2FkLXByb2R1/Y3Rpb24udHJhbnNp/c3Rvci5mbS9wZXJz/b24vZjIxMjQyNjAt/NDMwMy00ZWYzLWIz/MDQtMGU0ZTMxNjZl/ZGQ5LzE3MDcxNDYy/MzYtaW1hZ2UuanBn.webp)
![036: Game UI in Go with EbitenUI maintainer Mark Carpenter](https://img.transistor.fm/bF6iLV4xtxdYH5mX8t_vf_A5r7knvK8pvJT3yTiumtQ/rs:fill:800:800:1/q:60/aHR0cHM6Ly9pbWct/dXBsb2FkLXByb2R1/Y3Rpb24udHJhbnNp/c3Rvci5mbS9zaG93/LzI3MjkyLzE2NDE1/NjU2MDgtYXJ0d29y/ay5qcGc.webp)