modeless 8 days ago

Porting old games to the web is fun! Many are smaller than a typical modern webpage. They load fast and run great.

I just ported Quake 3 and I'm having some fun with it: https://thelongestyard.link/

  • geuis 8 days ago

    That was a lot of fun and a blast from the past. Thanks for porting that.

    • modeless 8 days ago

      Thanks! This is loading just the demo assets, but I got the Emscripten support merged into upstream ioquake3 so you can check out the code, build it yourself, and with the right game asset files you can play the full game, Team Arena, mods, or whatever.

      https://github.com/ioquake/ioq3/pull/658

      The only major feature missing from the original game is networking. Obviously kind of important for Quake 3. Should be possible with WebRTC DataChannel. And while the original game didn't have it, for the modern web a touchscreen control scheme is essential since half of everyone is on their phone. Of course it won't be great compared to mouse/keyboard but some mobile support is better than none. So those are the two features I'd like to add (besides performance optimizations; it's a bit slower than it should be for some reason).

  • Jyaif 7 days ago

    That input latency is why I hate browsers when making games.

    Great job though!

    • DonHopkins 7 days ago

      If you refactor and structure your code in the right way, you can get it to perform pretty well. What will kill you is stacking up layers of emulation, so you're feeding browser input into a Windows or Mac emulation layer, and even an x86 instruction set emulator, plus a useless obsolete operating system "middle ware", because the way input and animation works on old desktop guis is a lot different and much less efficient that how it works in the browser.

      It's certainly possible to run the original version of Mac or Windows SimCity in the browser inside a Mac or Windows emulator inside a WebAssembly module, but not only is the user interface itself terrible, klunky, and awkward, it's extremely slow and flakey because it's emulating all that obsolete operating system crap and instruction set underneath all the web browser crap between your mouse clicks and the game engine.

      Since the web browser is so much better and more flexible at user interface and graphics stuff, you want to totally strip all of the user interface and graphics and sound out of the game, implement an efficient API and callback mechanism (that doesn't spend a lot of time thunking and marshalling and unmarshalling parameters, and pass simple primitive data types, sending what you need all at once, instead of ping-ponging back and forth with proxy objects), and implement all of the UI in the browser (especially the animation timers and input handlers), calling back to the simulator only when necessary.

      One thing I did was to use shared memory between the WebAssembly module and the WebGL tile renderer, and write a custom shader that understands the native 16 bit unsigned int column major SimCity tile format, so WebGL only has to draw two triangles, and there is zero copying to draw the tiles.

      • pton_xd 7 days ago

        > and implement all of the UI in the browser (especially the animation timers and input handlers)

        I may have misunderstood you, but in my experience using the DOM for UI is a bad idea if performance is a concern. DOM updates in the browser are incredibly slow, especially for something like a game which wants to modify UI elements every frame. Meticulously avoiding relayouts, style recalculations, and other slowdowns is a constant headache.

        EDIT: run a few second performance profile of your site. Now do it again while waving the mouse back and forth over the UI links. Notice all the recalculate style and hit test calls that take more time than your entire WASM update! And that's with a UI that's doing nothing!

        • lukevp 7 days ago

          I think you did misunderstand their point. Browser native doesn’t just mean DOM, there’s also Canvas and directly reading mouse offsets and various other approaches. What they mean is don’t transit a mouse click through an OS emulation layer through a hardware emulation layer to the simulator, just directly read input from the browser and skip all the intermediate layers and inject the value directly to the code. Imagine that the mouse is simulating a PS2 hardware device with input polling and interrupts on top of a whole simulated OS and all that crap.

          The approach suggested is assuming you have access to the code to modify how it gets input data, or you’re willing to update the memory directly when input happens.

        • DonHopkins 7 days ago

          Since SimCity was originally designed to run on the C64, I don't think performance is too much of a concern on modern hardware, since it runs more than fast enough, and definitely wasn't intended to run at 120 frames per second running 50 simulation ticks per frame (which is what you get when you press the "9" key, and the user interface is still quite responsive on my M1 Mac).

          Although running it that fast is great for fast-forwarding time, but not practical for actually trying to build the city with the editing tools while it's running at such high speeds. Even 30 FPS with one tick per frame is too fast for most people to keep up with.

          When I developed it on a SparcStation 2 under the NeWS window system in 1991, the user interface was written completely in PostScript, which was orders of magnitude slower than JavaScript and WebAssembly, since it was interpreted, not compiled or JIT'ed or optimized in any way. But it still worked just fine, orders of magnitude faster than a C64, and could easily run at many years per second.

          The pie menus (which I'll implement soon for Micropolis) are able to reliably support quick gestural mouse-ahead interactions, even when the computer lags behind. And they made it a lot easier to play the game at high speeds (or when the computer is busy), because you didn't have to waste your time moving back and forth between the map and the tool palette, and you can quickly and easily change tools with swift reliable mouse-ahead gestures.

          When I showed it to user interface critic Don Norman, who makes a strong case for solving problems instead of focusing on technology, he actually complained about pie menus making SimCity too easy to build a city really quickly without even thinking about it.

          https://www.youtube.com/watch?v=5GCPQxJttf0

          Norman: "And then when we saw SimCity, we saw how the pop-up menu that they were doing used pie menus, made it very easy to quickly select the various tools we needed to add to the streets and bulldoze out fires, and change the voting laws, etc. Somehow I thought this was a brilliant solution to the wrong problems. Yes it was much easier to now to plug in little segments of city or put wires in or bulldoze out the fires. But why were fires there in the first place? Along the way, we had a nuclear meltdown. He said "Oops! Nuclear meltdown!" and went merrily on his way."

          Hopkins: "Linear menus caused the meltdown. But the round menus put the fires out."

          Norman: "What caused the meltdown?"

          Hopkins: "It was the linear menus."

          Norman: "The linear menus?"

          Hopkins: "The traditional pull down menus caused the meltdown."

          Norman: "Don't you think a major cause of the meltdown was having a nuclear power plant in the middle of the city?"

          (laughter)

          Hopkins: "The good thing about the pie menus is that they make it really easy to build a city really fast without thinking about it."

          (laughter)

          Hopkins: "Don't laugh! I've been living in Northern Virginia!"

          Norman: "Ok. Isn't the whole point of SimCity how you think? The whole point of SimCity is that you learn the various complexities of controlling a city."

          X11 SimCity Demo -- Demo of Pie Menus in SimCity for X11. Ported to Unix and demonstrated by Don Hopkins:

          https://www.youtube.com/watch?v=Jvi98wVUmQA

          Even the Flash client / Python server networked version runs plenty fast over the internet, and also supports pie menus:

          https://www.youtube.com/watch?v=8snnqQSI0GE

          Micropolis: Constructionist Educational Open Source SimCity:

          https://donhopkins.medium.com/har-2009-lightning-talk-transc...

          >The NeWS and X11 version both supported advanced user interface features like multiple animated maps and editors, as well as pie menus. The X11 version supported multiple player collaboration, shared text chat and drawing, and voting dialogs. And Unix workstations could run the simulation orders of magnitude faster than home computers, which transformed SimCity into a fast action twitch game!

          Of course it's fun to optimize just for the sake of optimization, but I think it's more interesting spending the time taking advantage of browser technologies like WebGL, HTML, CSS, Canvas, SVG, and other tools and libraries, to make a rich beautiful user interfaces with useful visualizations (like publishing analytic data into a time series database, and rendering it in tools like Grafana, or using D3 for data visualization).

          https://news.ycombinator.com/item?id=40065764

          I want to push as much of the user interface out of the engine and into JavaScript/HTML/Canvas/SvelteKit as possible, since it's so much easier to make much better more advanced user interfaces with a modern stack than trying to deal with a crufty Windows emulation layer, and make improvements to that kind of code.

          One thing I want to do is to make both Micropolis and Tower able to export lots of raw and cooked data, telemetry, and events, so I can use d3, Grafana, and other off-the-shelf data visualization tools to analyze and display the game state and history.

          A couple decades ago an Earth Science professor Upmanu Lall at Columbia University proposed a great idea about developing an educational version of SimCity to use in his classes aimed at engaging students from other departments and getting them interested in data analysis and science. He wanted SimCity to simply be able to export spreadsheets of data, and have the students perform experiments and analyze the data using standard tools like Excel. A game like SimCity or SimTower would be an engaging way to pique the student's interest, that they could relate to, and motivate and teach a general literacy and understanding of spreadsheets and data analysis and visualization tools!

          Upmanu Lall:

          https://www.columbia.edu/~ula2/

          Here's the Educational SimCity proposal I wrote, but it didn't go anywhere until many years later when we finally talked EA into relicensing SimCity under GPL-3 for the One Laptop per Child project.

          https://web.archive.org/web/20050403103131/http://www.donhop...

    • wffurr 7 days ago

      Pointerrawupdate events: https://w3c.github.io/pointerevents/#the-pointerrawupdate-ev... would help with that. If tearing is Ok, the canvas can be desynchronized and updated immediately.

      We can get 10 msec inking latency with those on a 60 Hz display.

      • modeless 7 days ago

        In the past I have experimented with pointerrawupdate and desynchronized, and I was unable to reproduce any latency benefit in practice. These features have a lot of caveats and are not reliable, in my experience, which is probably why practically nobody uses them. It's way too easy to fall off the fast path, if the fast path is even supported on your platform at all.

        Also, native apps have a lot of options to reduce latency without any risk of tearing artifacts, and it's unfortunate that web apps don't have access to those options. The web has a long way to go to match native on the latency front and there really hasn't been meaningful progress in that direction.

        I would like to experiment with pointerrawupdate and desynchronized again. But I'm currently relying on Emscripten's SDL implementation for input and drawing, and replacing or modifying that is daunting. After all, this is just a fun side project for me.

        A much easier and more widely supported latency fix would be to use a blocking API like WebGL's ReadPixels to synchronize the content process and GPU process and defeat the deep frame pipelining that the browser usually falls into, at some cost to performance. I plan to try that first.

      • CyberDildonics 7 days ago

        Is inking latency the new pixel to pixel latency or input to pixel latency? I like to keep up with the new names for old things.

        • modeless 7 days ago

          The features he's talking about were added to Chrome for ChromeOS/Win8 tablet stylus drawing support, which they refer to as "inking". They're kind of a specific fast path for that use case. They were not tested for any other use case and as a result tend not to be usable in practice due to various caveats, unfortunately.

  • langarus 7 days ago

    really love this. Where would one start in order to get better at this? Mainly porting old games to wasm

    • modeless 7 days ago

      Thanks! Emscripten is the tool that makes it relatively easy, for stuff with source code available. So I'd say pick something and try to build it with Emscripten.

      For stuff without source code you'll have to use emulation. DOSBox and MAME have web ports already. I haven't looked into them much. But the Internet Archive has a big collection of games that run in them already. So check that to see if the game you want is already available.

  • noxa 7 days ago

    my favorite map too :)

DonHopkins 7 days ago

Micropolis Web Demo 1: https://www.youtube.com/watch?v=wlHGfNlE8Os

Micropolis Web is the browser based version of Micropolis (open source SimCity), that uses WebAssembly, WebGL, and SvelteKit. Based on the original SimCity Classic code, designed by Will Wright, ported by Don Hopkins. This first demo shows an early version that runs the WebAssembly simulator and animates the tiles with WebGL, but most of the user interface is still a work in progress.

Live MicropolisWeb Site: https://MicropolisWeb.com

GitHub Repo with source code and documentation: https://github.com/SimHacker/MicropolisCore

Much more Info in Chaim Gingold's book, "Building SimCity": https://mitpress.mit.edu/9780262547482/building-simcity/

Chaim Gingold's "SimCity Reverse Diagrams": https://smalltalkzoo.thechm.org/users/Dan/uploads/SimCityRev...

Micropolis Web Space Inventory Cellular Automata Music 1: https://www.youtube.com/watch?v=BBVyCpmVQew

Micropolis Web is the browser based version of Micropolis (open source SimCity), that uses WebAssembly, WebGL, and SvelteKit. Based on the original SimCity Classic code, designed by Will Wright, ported by Don Hopkins. This first video has music by Juho Hietala, Blamstrain, and the Space Inventory Cellular Automata is performed by Don Hopkins.

Music by Juho Hietala, Blamstrain: https://blamstrain.com/

  • ziggy_star 7 days ago

    Mr Hopkins you are by far one of my favorite posters on this website and these sort of comments are golden.

    On occasion they get appropriate engagement but sometimes there are no replies.

    You should know that it does not go unnoticed. The breadcrumbs you leave will be followed by youngsters far into the future, a worthwhile endeavor.

    Thank you for brightening my sunday and everything you’ve done and your efforts at documenting and preservation.

    While HN is not what it used to be I consider you royalty and old school users like yourself are the reason many of us still frequent this place.

    You are appreciated sir. Cheers.

    • DonHopkins 7 days ago

      Thank you! It feels great to have finally gotten the code working well enough that other people can use it, and to hear your kind feedback! It makes it all worthwhile. I've gotten so much pleasure just staring at the cellular automata for hours on end that I wanted to make that work and share it, even if you can't play the game yet.

      It will be even more fun once I get the city editing tools and disasters menu working, so you can bulldoze and draw roads and buildings and release monsters to stomp around and cause other disasters in the cellular automata! They're also useful for building and destroying cities, too, but painting in the live cellular automata is even more fun.

      Here's an old blurry video of that on the X11 version:

      Cellular SimCity: Cellular Automata in SimCityNet on Unix.

      https://www.youtube.com/watch?v=P8KJ--drZO8

  • lioeters 7 days ago

    > Building SimCity: How to Put the World in a Machine

    Oh wow, this book by Chaim Gingold was just published on June 4, 2024. I loved the diagrams he made of SimCity algorithms, and I believe I read his dissertation(?) which goes into juicy details of how SimCity works internally. Ah here it is:

    Gingold, Chaim. “Play Design.” Ph.D. thesis, University of California Santa Cruz, 2016. https://www.proquest.com/docview/1806122688

    So the book I'm sure will be wonderful.

    ---

    The WASM port of Micoropolis sounds like it could be the start of a new stage in its development. SimCity Classic on the Macintosh was a big influence in my childhood, on how I think about computers and software. I'm happy to see new life breathed into it.

    • DonHopkins 7 days ago

      Yes, his thesis was outstanding, and a lot of the best parts ended up in the book.

      I really appreciated the big section at the beginning about Doreen Nelson's life work, Design Based Learning, which he also covered in depth in the Building SimCity book. She and Michael Bremmer wrote the SimCity Teacher's Guide (which Cliff Basinger (LGR) found on eBay, made an unboxing video review about, and sent me his copy of. I have been meaning to scan it and put it online -- I'll see if I can dig it up and scan it, since it would make a great addition to the Micropolis project).

      LGR - SimCity Educational Version Unboxing & Overview: An overview of the "School Edition" Lab Pack of SimCity Classic by Maxis. Unboxing, first impressions of the package and testing of the radically rad software ensues.

      https://www.youtube.com/watch?v=edXRNtuAGTg

      More about Doreen Nelson:

      https://news.ycombinator.com/item?id=21049206

      DonHopkins on Sept 23, 2019 | parent | context | favorite | on: OLPC’s $100 laptop was going to change the world (...

      >There were many reasons the OLPC failed, but I don't think constructionist education was one of them, when it's succeeded in so many other places.

      >EA donated SimCity to OLPC because of its relation to constructionist education, thanks to Maxis's collaboration with Doreen Nelson, who wrote the SimCity teacher's guide, and developed "City Building Education" and "Design Based Learning", in which kids built cities out of cardboard instead of pixels:

      https://news.ycombinator.com/item?id=20329281

      >SimCity can be used educationally, but not in the sense of literally training people to be urban planners or mayors. It's more useful for "Constructionist Education" and "Design Based Learning", as practiced by Seymour Papert and Doreen Nelson.

      >[...] One of the teachers [Clair] Curtin hired was Doreen Nelson, a brilliant and innovative educator who had developed a pedagogy called City Building Education, in which students collaboratively built cities out of craft materials and role play. Nelson become a regular visitor to Maxis, and Curtin made some trips to Los Angeles to see City Building in action, where she found the experience of “watching a classroom actually go through a couple of days worth of creation” to be “very inspiring. … I will never forget that experience” (Curtin 2015; Nelson 2015). [5]

      >[5]> This translation took the form of a short teacher’s guide, a pamphlet, really, written by Michael Bremer, and published by Maxis in 1989—the same year SimCity was released, explaining the limitations and applications of SimCity, and offering curricular questions and scripts. Within a few years, Maxis became more serious about tackling the education market, and hired Claire Curtin, in 1992, as their first educational product manager, charging her with finding ways to package SimCity, SimEarth, and SimAnt for the school market. Prior to joining Maxis, Curtin had been the senior producer of Brøderbund’s hit educational franchise, Where In The World Is Carmen Sandiego?, a job she had started in 1988, immediately after finishing graduate studies at NYU’s Educational Communication and Technology program, where she had studied with the noted education technology researcher Roy Pea. Over the course of her career at Maxis, Curtin shifted roles and projects, a result of Maxis’s fickle focus and its inability to produce hits beyond SimCity (chapter 5). Later, when Maxis defocused on a hard to reach education market, Curtin would go on to co-design or co-produce the kids’ titles SimTown (1995) and SimSafari (1998). Curtin collaborated closely with Roxana (“Roxy”) Wolosenko, and after Maxis decided not to do any more kid specific titles, the two of them were shifted to Wright’s “Dollhouse” project—a title that was not spoken out loud due to its gender connotations—where they were instrumental, as Wright’s co-designers, in evolving the design focus away from time management and towards people and interactions inspired by everyday life. It is this more human centric vision of Dollhouse that eventually saw release as The Sims, which became, at long last, the second commercially successful Sim title (Curtin 2015).

      >page 366> Play has a complex relationship to what is not play. Depending on who you ask, SimCity, the software toy, is either a frivolous diversion or an earnest model—and sometimes both. Right from the start, SimCity had appeal as an educational tool, a quality that Maxis tried to capitalize on. According to Braun, “It was never our intention to go into the education market, but the education market came to us and said: ‘This is what we need if you’re gonna work with us.’ ” What the education market wanted was teacher’s guides that translated and adapted SimCity for classroom use. It didn’t hurt that Brøderbund, Maxis’s publishing partner, was deep into the then hot educational software market, and that along with the investment Maxis received from venture capitalists in 1992, came a hunger for aggressive growth into new markets. Wright, of course, was busy making titles like SimEarth and SimAnt for an uncertain market. Maybe that market was education?

      Chaim also wrote a section in his thesis about open sourcing SimCity:

      Open Sourcing SimCity, by Chaim Gingold.

      https://donhopkins.medium.com/open-sourcing-simcity-58470a27...

      >Excerpt from page 289–293 of “Play Design”, a dissertation submitted in partial satisfaction of the requirements for the degree of Doctor in Philosophy in Computer Science by Chaim Gingold.

      His book also covered a lot of interesting stuff about cellular automata, including John von Neumann's 29 state cellular automata and universal constructor!

      Von Neumann Universal Constructor (wikipedia.org)

      https://news.ycombinator.com/item?id=22727228

      https://en.wikipedia.org/wiki/Von_Neumann_universal_construc...

      My JavaScript CAM6 cellular automata machine simulator has an implementation of it, but it needs a better user interface if you want to build a non-trivial machine (especially a self replicating one!)

      https://github.com/SimHacker/CAM6/blob/cbad2920fd0fab5b35baf...

      More about the theory of self reproducing cellular automata:

      https://news.ycombinator.com/item?id=32960377

      https://archive.org/details/theoryofselfrepr00vonn_0

      https://news.ycombinator.com/item?id=21855249

      "Signal crossing solutions in von Neumann self-replicating cellular automata", page 453-503

      https://donhopkins.com/home/documents/automata2008reducedsiz...

      https://news.ycombinator.com/item?id=21858465

      >>The von Neumann probe, nicknamed the Goo, was a self-replicating nanomass capable of traversing through keyholes, which are wormholes in space. The probe was named after Hungarian-American scientist John von Neumann, who popularized the idea of self-replicating machines.

      >Third, the probabilistic quantum mechanical kind, which could mutate and model evolutionary processes, and rip holes in the space-time continuum, which he unfortunately (or fortunately, the the sake of humanity) didn't have time to fully explore before his tragic death.

      >p. 99 of "Theory of Self-Reproducing Automata":

      >Von Neumann had been interested in the applications of probability theory throughout his career; his work on the foundations of quantum mechanics and his theory of games are examples. When he became interested in automata, it was natural for him to apply probability theory here also. The Third Lecture of Part I of the present work is devoted to this subject. His "Probabilistic Logics and the Synthesis of Reliable Organisms from Unreliable Components" is the first work on probabilistic automata, that is, automata in which the transitions between states are probabilistic rather than deterministic. Whenever he discussed self-reproduction, he mentioned mutations, which are random changes of elements (cf. p. 86 above and Sec. 1.7.4.2 below). In Section 1.1.2.1 above and Section 1.8 below he posed the problems of modeling evolutionary processes in the framework of automata theory, of quantizing natural selection, and of explaining how highly efficient, complex, powerful automata can evolve from inefficient, simple, weak automata. A complete solution to these problems would give us a probabilistic model of self-reproduction and evolution. [9]

      >[9] For some related work, see J. H. Holland, "Outline for a Logical Theory of Adaptive Systems", and "Concerning Efficient Adaptive Systems".

      https://www.deepdyve.com/lp/association-for-computing-machin...

      https://deepblue.lib.umich.edu/bitstream/handle/2027.42/5578...

      https://www.worldscientific.com/worldscibooks/10.1142/10841#...

yanslookup 7 days ago

I'm not a gamer but I remember playing SimCity as a kid... Did game play change in the last ~25 years or is my browser broken? It doesn't seem to do anything? I can load a city and watch it do things but I remember being able to actually build cities myself in SimCity... Is there supposed to be a way for players to... play?

parasti 7 days ago

This is cool. I didn't expect much on mobile (hey it's Simcity), but this page actually froze Firefox for me, on Android. Had to kill the process. That happens rarely.

BTW, here's a little game that I ported to the browser. Getting it to run was very straightforward (Emscripten+SDL2 is a great combo), but honestly making it fully playable on a phone took the most effort: https://play.neverball.org/

  • DonHopkins 7 days ago

    I fully intend to make it support mobile! And I already fixed one bug that prevented it from running on Firefox on Ubuntu, thanks to a well written bug report that included a stack trace. Give it another try, maybe it works now, and if not, please report the bug and include a stack trace and any information about your platform.

    https://github.com/SimHacker/MicropolisCore/issues/1

    I wanted to release this as soon as possible so other people could run it, instead of waiting until it was finished and perfect, so there's a lot more work to do on the user interface, robustness, cross platform support, mobile, etc.

    But once I got the simulator and tile renderer working, I threw together a minimalistic zooming panning + keyboard control interface, and a little window with hints that you can close by clicking the "+" button in the upper right corner.

    What I'm really looking forward to doing is integrating it with visual programming languages like Snap! so you can live code it and write plug-in zones, robots, monitoring and control systems, data visualization and export (i.e. Grafana dashboards, etc), and alternative interfaces via visual programming, instead of raw non-interactive JavaScript or TypeScript!

    Edit for parasti: You can use a USB cable to attach an Android phone to a Mac or PC, or an iPhone to a Mac, and then use the Chrome (or Safari on Mac) browser's debugger to attach to the phone and remotely see the console messages, debug, and even live code it! It might even work over Wifi if you can get all the stars to align, if Google hasn't canceled that feature, or if Apple hasn't forbidden it in the first place.

    • parasti 7 days ago

      That's awesome, looking forward to it. Would love to report more, but this is on Android - I wouldn't even know how to go about getting a stack trace. Being on Android, I can't even see the developer console.

  • noduerme 7 days ago

    This is shockingly high frame rate and stutter-free on a 4 year old bottom shelf android phone in firefox. Not that it's so many textures or polygons but even so I'm not used to anything performing remotely that well in a browser on this phone. Nice job!

    • parasti 6 days ago

      Thanks for giving it a try! Let me know if there's anything that needs improving.

  • Neywiny 7 days ago

    I'm also Firefox on Android and it didn't for me. Though I have noticed that some of the newer versions of Firefox can be kinda sucky for PDFs. Maybe it's linked to versions.

_ache_ 8 days ago

Seriously, I'm stun about what happen if you it the space bar. Nice fractals.

  • DonHopkins 7 days ago

    Game Helpin' Squad's review of World Quester 2 is the inspiration for the Space Inventory, and I aspire to design the Micropolis menus and user interface to be as freaking awesome as World Quester 2!

    https://www.youtube.com/watch?v=0Gy9hJauXns

simonebrunozzi 8 days ago

Wondering whether an LLM could be able to port a game like this instantly.

  • DonHopkins 7 days ago

    Good question, please don't downvote -- there's an interesting discussion to be had about that!

    The best approach is to use it like any other tool, and not expect it to do all the hard work for you, just relieve you of a lot of tedious work, and help you learn how to be a better programmer yourself, not replace you. There's no such thing as a free lunch, but some lunches are tastier and more nutritious and less expensive than others.

    I've been using ChatGPT to develop it, and it's helped a lot, and takes a great deal of iteration and guidance, but it's anything but instant.

    LLMs won't replace programmers, but programmers with LLMs will replace programmers without LLMs.

    Here's an example of how it was helpful in simply explaining the documentation and best practices of tools like Emscripten and Embind, getting the makefile to work, analyzing the code, categorizing methods and instance variables as private and public (to be wrapped by embind), generating the boilerplate Embind declarations, and writing the documentation through a back-and-forth discussion of goals and requirements, and acting like a glorified grep that actually understands the code syntax and accepts English queries instead of obscure command line arguments.

    The comments at the top (included below) were mostly written by ChatGPT in response to me writing the strategy, telling it in detail what I wanted to do, describing my goals, and how I wanted it to work, with lots of iterating and refining and hand editing:

    https://github.com/SimHacker/MicropolisCore/blob/main/Microp...

    The process was anything but automatic or instant -- in total it took about 33 years (and counting, I'm not done yet).

    I had to guide ChatGPT a lot, drawing from my previous experience porting the Mac version of SimCity to HyperLook on the NeWS window system in 1991, and other platforms later on.

    At the time I considered using a Mac compatibility library for X11, but that would have resulted in a terrible klunky user interface, could not have taken advantages of the Sun Workstation Unix programming and user interface environment (networking, big screen, better window management, pie menus and other nice user interface components, scalable color PostScript graphics and fonts, using native file formats for resources, audio mixing, lots of computing power to animate fast and zoom into the map, run the simulation super fast by skipping screen updates, profiling and optimizing the code, etc), tied the game to a proprietary library that is long obsolete, and would have only supported X11, not NeWS.

    For a game like SimCity, it was well worth throwing away the Mac UI, cleaning up the simulator to be independent of the UI, and writing a new high quality UI for HyperLook in NeWS (then later another for TCL/Tk in X11).

    Porting it to NeWS required separating the simulator from the user interface and defining a clean network API and shared memory raster animation library, rewriting the user interface in PostScript, and defining a messaging protocol between the simulator and UI.

    Then a few years later I ported that to TCL/Tk on X11, refactoring the simulator/UI messaging interface into TCL extensions. TCL/Tk made it possible to develop a networked multi-player version of SimCity.

    X11 SimCity Demo: https://www.youtube.com/watch?v=Jvi98wVUmQA

    Multi Player SimCityNet for X11 on Linux: https://www.youtube.com/watch?v=_fVl4dGwUrA

    TCL Doc: https://github.com/SimHacker/MicropolisCore/blob/main/notes/...

    Callbacks: https://github.com/SimHacker/MicropolisCore/blob/main/notes/...

    A couple of decades later, we made SimCity open source, released the TCL/Tk/X11 version for the OLPC and Linux, then I cleaned up and overhauled the simulator code into C++, and used SWIG to define the API and a callback mechanism, so I could plug it into Python.

    Micropolis Core: https://github.com/SimHacker/micropolis/tree/master/Micropol...

    Refactoring the code as C++ really helped modularize and organize it, made it easy to use doxygen to generate documentation, and much easier to wrap and port to different platforms.

    Doxygen documentation (current): https://micropolisweb.com/doc/

    Development Plan (old): https://github.com/SimHacker/MicropolisCore/blob/main/notes/...

    OLPC Plan (old): https://github.com/SimHacker/MicropolisCore/blob/main/notes/...

    To Do (old): https://github.com/SimHacker/MicropolisCore/blob/main/notes/...

    User Interface Plan (old): https://github.com/SimHacker/MicropolisCore/blob/main/notes/...

    OLPC Notes (old): https://github.com/SimHacker/MicropolisCore/blob/main/notes/...

    I implemented a couple of Python user interfaces, including a desktop based PyGTK/Cairo/X11 interface, and a web based TurboGears/AMF/OpenLaszlo/Flash client/server interface.

    Micropolis Online (SimCity) Web Demo (old): https://www.youtube.com/watch?v=8snnqQSI0GE

    Bil Simser used SWIG it integrate the simulator engine with C#. (SWIG's point is to integrate C++ code into many different scripting languages, not just Python.)

    C# Micropolis: https://github.com/SimHacker/micropolis/tree/master/Micropol...

    After all that work, and writing and executing on the design documents linked above, I had a pretty good idea how to prompt ChatGPT to write a design for the Emscripten/Embind API, and it was helpful for writing the boilerplate code, and validating the design, but not so much for coming up with the design in the first place.

    Beyond refactoring and wrapping the API, ChatGPT has also been extremely useful for learning the intricacies and best practices of TypeScript, SvelteKit, node, WebGL, canvas, CSS, HTML, etc, for developing the user interface.

        ////////////////////////////////////////////////////////////////////////
        // This file uses emscripten's embind to bind C++ classes,
        // C structures, functions, enums, and contents into JavaScript,
        // so you can even subclass C++ classes in JavaScript,
        // for implementing plugins and user interfaces.
        //
        // Wrapping the entire Micropolis class from the Micropolis (open-source
        // version of SimCity) code into Emscripten for JavaScript access is a
        // large and complex task, mainly due to the size and complexity of the
        // class. The class encompasses almost every aspect of the simulation,
        // including map generation, simulation logic, user interface
        // interactions, and more.
        //
        // Strategy for Wrapping
        // 
        // 1. Core Simulation Logic: Focus on the core simulation aspects, such
        //    as the methods to run the simulation, update game states, and handle
        //    user inputs (like building tools and disaster simulations). This is
        //    crucial for any gameplay functionality.
        // 
        // 2. Memory and Performance Considerations: JavaScript and WebAssembly
        //    run in a browser context, which can have memory limitations and
        //    performance constraints. Carefully manage memory allocation,
        //    especially when dealing with the game's map and various buffers.
        // 
        // 3. Direct Memory Access: Provide JavaScript access to critical game
        //    data structures like the map buffer for efficient reading and
        //    writing. This can be done using Emscripten's heap access functions
        //    (HEAP8, HEAP16, HEAP32, etc.).
        // 
        // 4. User Interface and Rendering: This part might not be necessary to
        //    wrap, as modern web technologies (HTML, CSS, WebGL) can be used for
        //    UI. However, providing some hooks for game state (like score, budget,
        //    etc.) to JavaScript might be helpful.
        // 
        // 5. Callbacks and Interactivity: Ensure that key game events and
        //    callbacks are exposed to JavaScript, allowing for interactive and
        //    responsive gameplay.
        // 
        // 6. Optimizations: Where possible, optimize C++ code for WebAssembly,
        //    focusing on critical paths in the simulation loop.
        // 
        // Decisions and Explanations
        //
        // - Excluded Elements:
        //       
        //     - Low-level rendering or platform-specific code, as this can be
        //       handled more efficiently with web technologies.
        //       
        //     - Parts of the code that handle file I/O directly, as file access
        //       in a web context is typically handled differently (e.g., using
        //       browser APIs or server-side support).
        //       
        //     - Any networking or multiplayer code, as web-based
        //       implementations would differ significantly from desktop-based
        //       network code.
        //
        // - Included Elements:
        //       
        //     - Core game mechanics, such as map generation, zone simulation
        //       (residential, commercial, industrial), disaster simulation, and
        //       basic utilities.
        //       
        //     - Game state management, including budgeting, scoring, and city
        //       evaluation.
        //       
        //     - Direct memory access to critical structures like the map
        //       buffer, allowing efficient manipulation from JavaScript.
        // 
        //     - Essential callbacks and event handling mechanisms to ensure
        //       interactivity.
        //
        // Conclusion
        // 
        // Given the complexity and size of the Micropolis class, wrapping the
        // entire class directly is impractical. However, focusing on key areas
        // essential for gameplay and providing efficient interfaces for
        // critical data structures can create a functional and interactive city
        // simulation in a web context. Further optimizations and adjustments
        // would likely be needed based on testing and specific requirements of
        // the web implementation.
        // 
        // Implementation Notes
        //
        // The enum_, class_, constructor, function, and property functions
        // from the emscripten namespace are used to specify how C++
        // constructs should be exposed to JavaScript. You can use these to
        // control which parts of your code are accessible and how they should
        // be used from JavaScript.
        //
        // I've made some assumptions here:
        //
        // The types MapValue and MapTile are simple types (like integers or
        // floats). If they are complex types, they would need their own
        // bindings.
        //
        // I'm assuming that the copy constructor and copy assignment
        // operator for the Position class are correctly implemented. If
        // they aren't, then the Position object may not behave as expected
        // in JavaScript.
        // 
        // Micropolis Binding Design
        //
        // The Micropolis interface organizes the Micropolis class header into
        // categories of functions that are relevant for interaction with the
        // JavaScript user interface, scripts, or plugins. The aim is to expose
        // functions that could help in monitoring and controlling game state
        // effectively.
        //
    • JKCalhoun 7 days ago

      > LLMs won't replace programmers, but programmers with LLMs will replace programmers without LLMs.

      I like that. I would darken it a bit though:

      "LLMs won't replace programmers, but a programmer with an LLMs might replace two programmers without LLMs."

      • zamadatix 7 days ago

        You could say the same thing about every improvement to programming workflows (version control systems, context aware editors, CI/CD, test frameworks, better languages/language improvements, package managers, Q&A repositories like StackOverflow, build systems, and so on). Whether you really consider increasing individual output dark/bad/ominous is up to you but if you apply that outlook historically you'll have had decades of negative outlook on the thought the job is going to become scarce while the number of high paying software jobs continued to increase despite efficiency improvements.

        In a more direct way: Making one programmer able to output what two programmers can do is almost always a gain for everyone involved. Making one programmer able to output what 10,000 programmers can do is a sign the field is being replaced. I don't think we'll get anywhere near concerns of the latter with LLMs.

      • cubefox 7 days ago

        A little bit darker:

        "LLMs won't replace programmers, but the LLM successors will."

        • DonHopkins 7 days ago

          Agreed -- I purposefully avoided saying "AI" instead of "LLMs" because LLMs aren't all that's required for AI to replace programmers. And my guess is that it will be a long time until AI replaces programmers.

usrbinbash 7 days ago

Why is there a fire department in almost every city block?!

  • DonHopkins 6 days ago

    Because fire fighters are awesome.

verbalstoner 7 days ago

Controls aren't working and as soon as the browser loaded something my CPU fan kicked in.

Are we sure this isn't just some janky crypto miner in disguise?

And if it isn't, what's the point of publishing something that doesn't work?

  • DonHopkins 7 days ago

    The point is to get feedback about how it works on different systems that I don't have access to.

    And it's better to get feedback from people as early as possible while you're developing software, than trying to fully complete it and make it perfect before ever releasing it to anyone. Especially open source software.

    The bottom line is that I simply can't afford to own every different type of computer and mobile phone, and even if I did, I don't have the time to test it on them all myself, since nobody's paying me to do this. But if you do want to pay me, you can be the first to support me via Patron, which I'd appreciate, but is not necessary.

    https://www.patreon.com/DonHopkins

    But that's not why I'm working on the project: it's a labor of love, not a source of income. However, I am running a special offer right now where you can pay me $5 to shut the fuck up for 5 minutes a month about any topic you want.

    You are free to examine all of the source code on Github, and report bugs, and build it yourself. And your web browser also has excellent built-in debugging and reverse engineering tools that you can use to examine the WebAssembly binary and pretty print the compiled JavaScript, if that would make you less anxious. The WebGL shader is in plain text, so you can read that too, and verify that it matches the source code in the repo.

    https://github.com/SimHacker/MicropolisCore

    And if you can find any evidence of janky crypto mining software, you are free to report me to the FBI and Interpol and Github, since it's quite easy to identify where the software came from and track me down, as I'm publishing the source code and binary under my own name from my own Github account and domain.

    Here's is a great example for you to emulate of somebody helpfully reporting an issue, identifying the system they're using, and including a stack trace identifying the problem, which I was able to fix in a few minutes.

    https://github.com/SimHacker/MicropolisCore/issues/1

    I'm glad you're so motivated to engage with the open source software community, and I hope you can write such a useful bug report yourself, and possibly even fix it yourself and submit a PR!

    Did you try pressing the numeric keys to control the speed? (I haven't tested it with a numeric keypad, which I don't have, so use the digits along the top of the keyboard.) If you press "1" it slows down to one frame per second with one simulator tick per frame, while "9" runs at 120 frames per second with 50 simulator ticks per frame. That runs smoothly in Chrome on my M1 Mac, and the user interface is still quite responsive.

    Which controls aren't working? What hardware and operating system and browser and GPU are you using, and did you see any error message printed on the browser developer console? Please include any console stack traces in your bug reports.

robblbobbl 7 days ago

Good job! Now we need a Age of Empires and Empire Earth port!

TapamN 7 days ago

I worked on a port of Micropolis to the Sega Dreamcast, but never finished it.

https://www.youtube.com/watch?v=MlFu-y1LDbs

One thing I really disliked about the SNES port of SimCity Classic was how slow the interface was. Having to access the menu for everything was a pain. For my port, the cursor would move faster, and snap instantly to the next tile if it was tapped. The analog stick could be used for fast cross map movement. The menuing was replaced by mapping every command to a button combination, with different palettes of commands available depending on what shoulder buttons were pressed.

If you weren't holding a shoulder button, the ABXY buttons were set up for A (primary action button) for roads, X (secondary action) for rail, Y (the green button) for parks, and B (cancel button) for bulldozer. Holding L was reserved for system commands, you could zoom in or out with A or Y, and adjust the speed with X and B. Holding R completely would allow building zones, color coded to the controller's buttons, with the red (A) button to build residential, blue (B) for commercial, and yellow (X) for industrial. There were two more palettes, accessed by either pressing L+R, or half pressing the R button, for infrequently built things like power plants and airports. It might sound complicated from the description, but I think it would be pretty easy to get used to if you actually tried it a bit.

I did a bit more work after I made the video, like adding map overlays (pollution, traffic, etc) and a display of what the current face button palette is, to help learn the combinations.

I was also adding split screen, for multiplayer. I was planning for you to be able either build a city together with someone else, or do competitive city building, like race to clear a scenario, or get the highest population or funds in a certain amount of time. I think I got the split screen two different cameras on the same city working, but no controls for anyone besides player 1.

I spent some time optimizing the simulation, because I wanted absolute solid 60 FPS. There would be occasional 1 or 2 frame stutters on large cities went certain phases of the simulation ran. The worst was when it calculated power.

The power grid connectivity is calculated in a bizarre way. Instead of a regular, scanline based flood fill, it basically has a Logo turtle walk the power grid. It uses the exact same class that the monster uses for movement, tracking the facing of the turtle, with functions to turn, take one step forward, etc. The version of GCC I was using was not automatically inlining the movement functions (they were in .CPP files, and no LTO), so it added a ton of overhead to an already slow algorithm. I moved the functions into the header so they would be inlined, which helped a lot, but was still planning to replace the whole thing with a real flood fill.

Even after inlining the walker, there were still single frame stutters. A lot of the map data for things like pollution and land value have filters applied to them, and the filter has a slow implementation. It does X and Y bounds checking on every tap of the filter, even in the middle when it can't go out of bounds. A better filter implementation would have helped.

The C++ simulation seemed to have some kind of bug, which would cause periodic mass abandonment, that I never figured out. I never noticed the Java version having the same problem.

  • DonHopkins 7 days ago

    Amazing!

    Decades ago, Will Wright suggested to me a nice optimization for cellular automata and convolution filters that lets you eliminate the bounds checks in the inner loop, which I implemented in my CAM6 cellular automata machine simulator:

    Eliminate the edge conditions (and conditionals in the inner loop) by making a "gutter" of one extra pixel (or however many pixels your neighborhood extents out) around all the edges of the bitmap (i.e. increase the width and height by 2, then inset x and y by 1), then before processing each frame, copy the appropriate edges into the corresponding gutters (wrapping or clamping), then iterate over the pixels just inside the gutters, so you don't have to perform any bounds checks.

    https://github.com/SimHacker/CAM6/blob/master/javascript/CAM...

        // Optimization Techniques
        //
        //   Extra copying is eliminated by swapping between two cell buffers,
        //   one for the past and the other for the future. After applying the
        //   rule, the past cell buffer becomes the future, and the future
        //   becomes the past.  It's necessary to have two buffers, because
        //   you can't apply cellular automata in-place in one buffer, since
        //   you would stomp on your past neighbors whose future you just
        //   computed, since the neighbors above and to the right would be
        //   from the future instead of the past.
        //
        //   Edge conditions eliminated from inner loop by making cell buffers
        //   two cells wider and taller, and wrapping edges around to the
        //   extra edge cells before applying rule, so the inner loop does not
        //   have to check for edge conditions to wrap the cells, and other
        //   edge treatments can be applied besides wrapping, like clamping or
        //   reflecting.
        //
    
    https://github.com/SimHacker/CAM6/blob/master/javascript/CAM...

        // wrapCells wraps the cell edges.
        [...]
    
    You can either wrap the cells into the gutter from the opposite edge like a torus, which makes nice seamlessly tileable patterns, or in the case of something like SimCity pollution diffusion, you can just clamp the pixels into the gutter along the same edge.

    Shaders have a way of wrapping and clamping and mirroring automatically (wrapping modes):

    https://webglfundamentals.org/webgl/webgl-3d-textures-repeat...

    But on old school consoles you have have to use software tricks like that instead of relying on the hardware.

    And of course if you're using power of two sized bitmaps you can just mask the coordinates, which is practically free.

    You could fix SimCity to use that trick, but it would make the code more complex, and it's probably not worth it on anything but really old hardware like the C64 or Sega Dreamcast.

gnfedhjmm2 8 days ago

It’s funny I was thinking about writing some browser based games using Pyscript with web assembly. But now I think by the time I finish the games they’ll have ported enough of Python into web assembly that I might as well write it with Kivy or Pygame and then it would be cross platform. Pygame already in the browser, but slow and clunky IMO. In 6 months who knows?

  • nextaccountic 8 days ago

    Don't let analysis paralysis deter you from writing games. Pyscript is fine. Other stuff is fine too. Pick whatever technology you want, and make quick games with rapid prototyping. Join some game jams and keep your scope small. It's better to create and ship many small games.

    About pygame in the browser: check out pygbag.

    • gnfedhjmm2 8 days ago

      Would like technical thoughts, not cheerleading. I’ve written many games before just not with a new shaky stack.

      • nextaccountic 4 days ago

        Oh but in technical terms my thoughts are completely opposite. Python wouldn't be my first choice for games in general, and much less for web games.

        Really the only way to justify using Python in this domain is if you're more comfortable with Python than other languages, and what you are building is a small, lightweight game. But this is reason enough to validate the idea! So if you want to build a game with Python, go for it.

        But if you're minimally comfortable with Typescript it would be a seriously better fit for this domain. Something like https://github.com/pixijs/pixijs will work much better than Pygame or anything. It's geared towards simple 2D games too.

        One reason for that is dependencies. By using Python with Pyscript you will be constrained with what libraries you can use, because not all of them is compatible with Pyscript.

        (I myself am more comfortable with Rust, and Rust libraries like https://github.com/not-fl3/macroquad can target browsers, desktop and mobile; and it's also meant for simple 2D games. And I prefer the Rust ecosystem of libraries, too)

      • JKCalhoun 7 days ago

        Some of us appreciated the cheerleading though. :-)