TCP/UDP/WebSocket multiplayer 2D game in Go (with web client), for fun

xuanbao · · 1620 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>(This is a cross post from <a href="/r/gogamedev">r/gogamedev</a>, but I thought it&#39;d be interesting for people here since this is pure Go and it deals with interesting things like <code>net.Conn</code>, channels/select statements, etc., and having it work cross-platform.)</p> <p>I&#39;m a big fan of Go and I think it has amazing potential for making games. I&#39;m interested in pushing its limits and finding out how far it can go, and so far it&#39;s a blast!</p> <p>I wanted to share a little game project I&#39;m working on in my spare time. It&#39;s written 100% in pure Go, aside from some cgo dependencies for OpenGL and GLFW. It&#39;s actually a port of an unfinished original version I started many years ago in C++.</p> <p>I took a look at Go&#39;s <code>net</code> package and wanted to see how hard it&#39;d be to send some TCP/UDP packets and have it connect to the C++ server... then ported the server, added logic, a simple renderer, and by now a large part is working in Go.</p> <p>Here&#39;s a <a href="https://raw.githubusercontent.com/shurcooL/eX0/master/eX0-go/Screenshot.png">screenshot</a> to give you an idea. I&#39;m working on the netcode/gameplay first, so the graphics are very basic for now. The C++ version looked <a href="https://camo.githubusercontent.com/89b4b80e3237e59f703ec814a10b6f9c55922ebf/68747470733a2f2f646c2e64726f70626f7875736572636f6e74656e742e636f6d2f752f383535343234322f646d697472692f70726f6a656374732f6558302f53637265656e73686f742e706e67">slightly better</a>.</p> <p>Anyway, let me get to the cool part. One of the goals I had when I started the Go port was to be able to have the game client run in a browser. I wanted to use GopherJS compiler and WebGL.</p> <p>But there&#39;s no easy way to send UDP packets form the browser, so how did I get around that? For now, I use a WebSocket connection (which is a TCP-like connection) and marshall my TCP+UDP packets over that stream. It was great to be able to do this in Go because I could use channels/select statements (that I never had in C++) like you can see <a href="https://github.com/shurcooL/eX0/blob/91ae2559d3e860ff7454f330ff6efe2b92b9110e/eX0-go/net_tcp.go#L22-L103">here</a>.</p> <p>The original networking protocol uses TCP/UDP packets (and my Go version is currently staying compatible with the original C++ version), but I have 3 transport types: normal UDP/TCP via &#34;net&#34; package (see <code>net.go</code> file). Combined virtual TCP+UDP mode over WebSocket (<code>net_tcp.go</code>). And using Go channels (<code>net_chan.go</code>), which obviously only works when both the client and server are running in the same process. It gets unbeatably low ping times though!</p> <p>I said there&#39;s a web client, and you can try that just by clicking on this link in any modern browser (it even works on mobile, but I don&#39;t have touch controls):</p> <p><a href="http://dmitri.shuralyov.com/projects/eX0/eX0-go-client/">http://dmitri.shuralyov.com/projects/eX0/eX0-go-client/</a></p> <p>Arrow keys and W/A/S/D to move around. That&#39;s it for now.</p> <p>(Try opening two windows if there&#39;s no one else online, and try moving around. Open dev console to see networking info.)</p> <p>The source code is all here at <a href="https://github.com/shurcooL/eX0/tree/master/eX0-go#ex0-go-">https://github.com/shurcooL/eX0/tree/master/eX0-go</a>. Feel free to star the repo or watch it for further development news. I&#39;m happy to answer questions (with possible delay)!</p> <hr/>**评论:**<br/><br/>Gacnt: <pre><p>Is that dust 1 B site from counter strike. </p></pre>sh41: <pre><p>Yep, hehe.</p></pre>Gacnt: <pre><p>Haha neat, if you got time later feel free to check out the help request post I posted on here. Cool project though!!</p></pre>tathata: <pre><p>The project is down now, but thanks for sharing. I too am writing an in-browser game in Go and have a question about your front-end:</p> <p>I&#39;m a kernel engineer by day so the server-side stuff has not been a problem but the front end is looming. I&#39;m ramping up my environment to support developing JS now (my dev server is a CLI CentOS VM, so I&#39;ve been distracted setting up Samba to view the html easily etc.) but GopherJS looks interesting. I feel like as someone completely new to Javascript I&#39;d be better off trying to write it natively so I &#39;get&#39; it more, and GJS doesn&#39;t exactly look tidy, but of course it would be more convenient. Could you describe your experience with it?</p> <p>Thanks and good luck!</p></pre>sh41: <pre><p>It&#39;s not down, you might just have to wait 5-10 seconds for it to load. Try again and check the dev console, let me know if you see any errors there.</p> <blockquote> <p>GJS doesn&#39;t exactly look tidy,</p> </blockquote> <p>Can you please point out which parts you&#39;re referring to that don&#39;t look tidy? In my experiene it&#39;s been the opposite, my JavaScript tends to be messy/hacky, whereas I can structure the same code to be a lot nicer and cleaner in Go.</p> <blockquote> <p>I feel like as someone completely new to Javascript I&#39;d be better off trying to write it natively so I &#39;get&#39; it more</p> </blockquote> <p>It really depends on what you want to do. If you want to learn more JavaScript because it&#39;s what everyone uses and is therefore a safe option, or because you want to have a more marketable skill, then JavaScript is the way to go. If you want to be adventurous, or if you simply don&#39;t care about learning JavaScript but rather want to write some Go to accomplish your goals, and having that Go run in the browser is a nice relatively free addition that is enabled via GopherJS, then go with Go. I write in Go because I enjoy it a lot more and because I think it&#39;s a better future to invest into. I expect someday Go will be able to be a first class citizen language in the browser, and I&#39;m just getting a head start with that incredible experience.</p> <p>It also depends on your game. If it&#39;s a fullscreen OpenGL ES app, then using GopherJS to have a web client is likely to be very little extra effort and wouldn&#39;t require you to learn a different language and write a lot of the same code in it. If you&#39;re building it from scratch with a browser in mind and want to use normal HTML5 stuff, then maybe you&#39;d want to use JavaScript. Not that you couldn&#39;t use Go if you wanted to. In the end, which language you choose to use is up to you.</p> <blockquote> <p>Could you describe your experience with it?</p> </blockquote> <p>My experience with it has been incredible. I tried/started using it with <a href="https://github.com/shurcooL/atom-markdown-format/commit/6b5f21c4457309f8eba3a78b82e0c9a458ff13b4" rel="nofollow">porting 11k+ lines of Go code</a> (counting dependencies but not stdlib) in markdownfmt to run it natively in Atom (which runs JavaScript). After that, I&#39;ve pretty much switched to using GopherJS for all my personal front-end needs. It works really well and it&#39;s a lot of fun building clean, great solutions. But there&#39;s much work to do to catch up to the JavaScript world since it had a huge headstart.</p></pre>sh41: <pre><p>I&#39;ve added instructions for compiling and running the client in browser locally, for anyone interested.</p> <p><a href="https://github.com/shurcooL/eX0/tree/master/eX0-go#browser" rel="nofollow">https://github.com/shurcooL/eX0/tree/master/eX0-go#browser</a></p></pre>: <pre><p>[deleted]</p></pre>sh41: <pre><p>What I mean by TCP-like is that it has properties more similar to TCP (reliable, ordered, no duplicates, byte stream/connection based) than UDP (unreliable, unordered, possible duplicates, only individual packets).</p> <blockquote> <p>WebSocket is a protocol providing full-duplex communication channels over a single TCP connection. Additionally, WebSocket enables streams of messages on top of TCP. TCP alone deals with streams of bytes with no inherent concept of a message.</p> </blockquote> <p>I choose to ignore the messages of WebSockets and treat it as a stream of bytes in my code.</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1620 次点击  ∙  1 赞  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传