index.html (10117B)
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <title> 6 Plato Desktop Client · Jack Mordaunt 7 </title> 8 <meta charset="utf-8"> 9 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 10 <meta name="color-scheme" content="light dark"> 11 12 13 14 15 <meta name="author" content="Jack Mordaunt"> 16 <meta name="description" content="Desktop game client in Go."> 17 <meta name="keywords" content="blog,developer,personal,software,robust,performance,sovereign"> 18 19 20 21 <meta name="twitter:card" content="summary"> 22 <meta name="twitter:title" content="Plato Desktop Client"> 23 <meta name="twitter:description" content="Desktop game client in Go."> 24 25 <meta property="og:url" content="http://jackmordaunt.com/projects/plato-desktop-client/"> 26 <meta property="og:site_name" content="Jack Mordaunt"> 27 <meta property="og:title" content="Plato Desktop Client"> 28 <meta property="og:description" content="Desktop game client in Go."> 29 <meta property="og:locale" content="en"> 30 <meta property="og:type" content="article"> 31 <meta property="article:section" content="projects"> 32 <meta property="article:published_time" content="2025-07-17T11:21:04-03:00"> 33 <meta property="article:modified_time" content="2025-07-17T11:21:04-03:00"> 34 <meta property="article:tag" content="Go"> 35 <meta property="article:tag" content="Gio"> 36 <meta property="article:tag" content="Native"> 37 <meta property="article:tag" content="Portfolio"> 38 39 40 41 42 <link rel="canonical" href="http://jackmordaunt.com/projects/plato-desktop-client/"> 43 44 45 <link rel="preload" href="/fonts/fa-brands-400.woff2" as="font" type="font/woff2" crossorigin> 46 <link rel="preload" href="/fonts/fa-regular-400.woff2" as="font" type="font/woff2" crossorigin> 47 <link rel="preload" href="/fonts/fa-solid-900.woff2" as="font" type="font/woff2" crossorigin> 48 49 50 51 52 <link rel="stylesheet" href="/css/coder.min.6445a802b9389c9660e1b07b724dcf5718b1065ed2d71b4eeaf981cc7cc5fc46.css" integrity="sha256-ZEWoArk4nJZg4bB7ck3PVxixBl7S1xtO6vmBzHzF/EY=" crossorigin="anonymous" media="screen" /> 53 54 55 56 57 58 59 60 61 62 <link rel="stylesheet" href="/css/coder-dark.min.a00e6364bacbc8266ad1cc81230774a1397198f8cfb7bcba29b7d6fcb54ce57f.css" integrity="sha256-oA5jZLrLyCZq0cyBIwd0oTlxmPjPt7y6KbfW/LVM5X8=" crossorigin="anonymous" media="screen" /> 63 64 65 66 67 68 69 70 <link rel="stylesheet" href="/css/custom.min.931a9d02d6f7655cd0cd50317fac1204e00c54ffd0232085acc957b2db5e1283.css" integrity="sha256-kxqdAtb3ZVzQzVAxf6wSBOAMVP/QIyCFrMlXstteEoM=" crossorigin="anonymous" media="screen" /> 71 72 73 74 75 76 77 <link rel="icon" type="image/svg+xml" href="/images/self-tiny-white.svg" sizes="any"> 78 <link rel="icon" type="image/png" href="/images/self-tiny-white.png" sizes="32x32"> 79 <link rel="icon" type="image/png" href="/images/self-tiny-white.png" sizes="16x16"> 80 81 <link rel="apple-touch-icon" href="/images/apple-touch-icon.png"> 82 <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png"> 83 84 <link rel="manifest" href="/site.webmanifest"> 85 <link rel="mask-icon" href="/images/safari-pinned-tab.svg" color="#5bbad5"> 86 87 88 89 90 91 92 93 <script defer data-domain="jackmordaunt.com" src="https://plausible.io/js/script.js"></script> 94 95 96 97 98 </head> 99 100 101 102 103 104 105 <body class="preload-transitions colorscheme-auto"> 106 107 <div class="float-container"> 108 <a id="dark-mode-toggle" class="colorscheme-toggle"> 109 <i class="fa-solid fa-adjust fa-fw" aria-hidden="true"></i> 110 </a> 111 </div> 112 113 114 <main class="wrapper"> 115 <nav class="navigation"> 116 <section class="container"> 117 118 <a class="navigation-title" href="http://jackmordaunt.com/"> 119 Jack Mordaunt 120 </a> 121 122 123 <input type="checkbox" id="menu-toggle" /> 124 <label class="menu-button float-right" for="menu-toggle"> 125 <i class="fa-solid fa-bars fa-fw" aria-hidden="true"></i> 126 </label> 127 <ul class="navigation-list"> 128 129 130 <li class="navigation-item"> 131 <a class="navigation-link " href="/posts/">Blog</a> 132 </li> 133 134 <li class="navigation-item"> 135 <a class="navigation-link " href="/about/">About</a> 136 </li> 137 138 <li class="navigation-item"> 139 <a class="navigation-link " href="/projects/">Projects</a> 140 </li> 141 142 <li class="navigation-item"> 143 <a class="navigation-link " href="/contact/">Contact</a> 144 </li> 145 146 <li class="navigation-item"> 147 <a class="navigation-link " href="/pay-with-bitcoin/">Pay</a> 148 </li> 149 150 151 152 </ul> 153 154 </section> 155 </nav> 156 157 158 <div class="content"> 159 160 <section class="container page"> 161 <article> 162 <header> 163 164 <h1 class="title"> 165 <a class="title-link" href="http://jackmordaunt.com/projects/plato-desktop-client/"> 166 Plato Desktop Client 167 </a> 168 </h1> 169 170 </header> 171 172 <style> 173 .carousel { 174 display: flex; 175 overflow: scroll; 176 } 177 </style> 178 <div class="carousel"> 179 <img src="/images/Plato/PlatoHome.webp" alt="Home Page" /> 180 <img src="/images/Plato/PlatoGame.webp" alt="Game Page" /> 181 <img src="/images/Plato/PlatoMulti.webp" alt="Multi Window" /> 182 </div> 183 <h2 id="overview"> 184 Overview 185 <a class="heading-link" href="#overview"> 186 <i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"></i> 187 <span class="sr-only">Link to heading</span> 188 </a> 189 </h2> 190 <p>A cross-platform desktop game client built for <strong>Plato Team Inc.</strong>, supporting Windows, macOS, and Linux. Though now discontinued, the project showcased a modern, multi-window architecture with a primary chat interface and independent game windows.</p> 191 <p>The application was built in <strong>Go</strong>, using the <strong>Gio</strong> immediate-mode GUI toolkit. It interfaced extensively with C and C++ libraries, including <strong>ANGLE</strong> (OpenGL ES), <strong>V8</strong> (JavaScript engine), <strong>SQLite</strong>, and <strong>libwebp</strong> for image decoding.</p> 192 <hr> 193 <h3 id="my-role"> 194 My Role 195 <a class="heading-link" href="#my-role"> 196 <i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"></i> 197 <span class="sr-only">Link to heading</span> 198 </a> 199 </h3> 200 <p>As one of two primary developers, I contributed across the full stack, with a focus on architecture, performance, and cross-platform integration.</p> 201 <ul> 202 <li> 203 <p><strong>Reactive GUI Architecture</strong><br> 204 Co-developed a highly concurrent, fully reactive GUI system using <strong>Gio</strong> and <strong>SQLite</strong>. Built a declarative state model with the database as the single source of truth, enabling seamless multi-window synchronization.</p> 205 </li> 206 <li> 207 <p><strong>Tooling & Abstractions</strong><br> 208 Created reusable libraries and tooling (<a href="https://git.sr.ht/~gioverse/skel" class="external-link" target="_blank" rel="noopener">skel</a>) for stream-based data handling and safe inter-window communication. This enabled clean separation of concerns and race-free concurrency.</p> 209 </li> 210 <li> 211 <p><strong>Auto-Updater System</strong><br> 212 Designed and implemented a binary patch-based self-updater for seamless client updates with minimal bandwidth usage.</p> 213 </li> 214 <li> 215 <p><strong>Embedded Game Logic</strong><br> 216 Integrated game runtime logic using <strong>V8</strong>, communicating over a custom binary protocol with a proprietary backend.</p> 217 </li> 218 <li> 219 <p><strong>Deep OS Integration</strong><br> 220 Delivered native features on both Windows and macOS:</p> 221 <ul> 222 <li>Implemented <strong>Windows COM interfaces in pure Go</strong> for AAC audio decoding and system toast notifications.</li> 223 <li>Used <strong>Objective-C and C</strong> on macOS for native audio and system notification support.</li> 224 </ul> 225 </li> 226 </ul> 227 <hr> 228 <p>This project demanded <strong>low-level systems programming</strong>, <strong>high-concurrency architecture</strong>, and custom GUI tooling—all within the Go ecosystem. It reflects my ability to deliver <strong>production-ready, cross-platform software</strong> with deep OS integration and thoughtful abstractions.</p> 229 <h3 id="platforms"> 230 Platforms 231 <a class="heading-link" href="#platforms"> 232 <i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"></i> 233 <span class="sr-only">Link to heading</span> 234 </a> 235 </h3> 236 <div style="display: flex; flex-wrap: wrap; gap: 2rem;"> 237 <i class="fa-4x fa-brands fa-windows"></i> 238 <i class="fa-4x fa-brands fa-apple"></i> 239 <i class="fa-4x fa-brands fa-linux"></i> 240 </div> 241 <h3 id="languages"> 242 Languages 243 <a class="heading-link" href="#languages"> 244 <i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"></i> 245 <span class="sr-only">Link to heading</span> 246 </a> 247 </h3> 248 <div style="display: flex; flex-wrap: wrap; gap: 2rem;"> 249 <img style="max-height: 100px;" src="/images/brands/go.svg"/> 250 <img style="max-height: 100px;" src="/images/brands/c.png"/> 251 </div> 252 <h3 id="tech"> 253 Tech 254 <a class="heading-link" href="#tech"> 255 <i class="fa-solid fa-link" aria-hidden="true" title="Link to heading"></i> 256 <span class="sr-only">Link to heading</span> 257 </a> 258 </h3> 259 <div style="display: flex; flex-wrap: wrap; gap: 2rem;"> 260 <img style="max-height: 100px;" src="/images/brands/gio.svg" class="invert-me"/> 261 <img style="max-height: 100px;" src="/images/brands/sqlite.svg"/> 262 <img style="max-height: 100px;" src="/images/brands/opengl.svg"/> 263 <img style="max-height: 100px;" src="/images/brands/v8.svg"/> 264 </div> 265 266 </article> 267 </section> 268 269 270 271 </div> 272 273 <footer class="footer"> 274 <section class="container"> 275 © 276 277 2025 278 Jack Mordaunt 279 · 280 281 Powered by <a href="https://gohugo.io/" target="_blank" rel="noopener">Hugo</a> & <a href="https://github.com/luizdepra/hugo-coder/" target="_blank" rel="noopener">Coder</a>. 282 283 </section> 284 </footer> 285 286 </main> 287 288 289 290 291 292 <script src="/js/coder.min.6ae284be93d2d19dad1f02b0039508d9aab3180a12a06dcc71b0b0ef7825a317.js" integrity="sha256-auKEvpPS0Z2tHwKwA5UI2aqzGAoSoG3McbCw73gloxc="></script> 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 </body> 334 </html>