Impact was so ahead of its time. Proud to say I was one of the 3000 license owners. One of the best purchases I’ve ever made. The only game I’ve ever really properly finished was made in Impact.
I loved that the source code was part of the license, and even modified the engine and the editor to suit my needs.
I was so inspired that I worked on my own JS game engine (instead of finishing games - ha!) for years after. I never released it, but I learned a ton in the process and made a lot of fun gamejam games with it.
I was also inspired by Impact’s native iOS support (Ejecta), but frustrated that it didn’t run on Android (at the time at least), so I fumbled my way through writing JVM bindings for V8 and implemented a subset of WebGL to run my game engine on Android without web views.[0] I made the repo for V8 bindings public and to my surprise it ended up being used in commercial software.
I won’t bore you with the startup I tried to bootstrap for selling access to private GitHub repos, which was inspired by Impact’s business model…
Anyway, it warms my heart and makes me laugh with glee to see Impact getting an update for the “modern” web with a C port!
I’d say these are strange times for the web, but I can’t remember a time when things were anything but strange. Cheers!
Cross Code is an excellent game. I knew that it used web tech and I was constantly amazed by how performant it was on the Nintendo Switch hardware. I would guess that this engine deserves some credit there!
Imho, that's fantastic! I love to see devs being able to adapt the engine for their particular game. Likewise, high_impact shouldn't be seen as a “feature-complete” game engine, but rather as a convenient starting point.
You can't polish a turd. There would've been no point in modifying the engine a bunch if you hadn't given them a useful base to work with.
For the anecdote, everyone wanted a Switch version, but considering the technical limitation, the team replied with "Sorry but CrossCode will be coming to Switch when Hedgehags learn to fly." [1] When they finally got to do it [2], it came with an extra quest called "A switch in attitude", featuring, you guessed it, flying hedgehags.
[1] https://www.radicalfishgames.com/?p=6581 [2] https://www.radicalfishgames.com/?p=6668
So, if I understand correctly, this is roughly what he did:
1. Wrote a transpiler to convert the subset of Javascript used by CrossCode into a dialect of Haxe.
2. Selectively modified his version of Haxe in small ways to more closely match the semantics of Javascript, to make writing the transpiler easier.
3. Selectively re-wrote complicated parts of the Javascript code into Haxe directly, so that his transpiler didn't have to handle them.
4. Transpiled <canvas> and other browser API calls into calls to his own pre-existing Kha framework for Haxe, which provided similar APIs.
5. Compiled the Haxe output into C++.
6. Compiled the C++ to native code.
Damn.
I for example basically ignore the shield for the vast majority of the game, only doing some very basic usage for some bosses, but perfect counters could very well be your favorite thing.
I believe that somewhere in there was frustration with Adobe who seemed to abandon the MacOS platform support for Windows' much larger user base, eg. Mac versions were always behind Windows versions. Perhaps Jobs also may've felt that there would be no Adobe without Apple as much as the other way around but that's speculative
The game looks slick af btw,
As someone who is interested in eventually freeing myself from the corporate job and diving head-first into my side projects, I would love to hear more about this aspect.
For some reason the idea of trying to charge folks for the work I would normally do for the fun of it on the side is daunting to me, even though I know it could enable me to focus on doing the stuff I love full-time.
So I think it's important to figure out why the idea of doing that is daunting to you. Some common "reasons" are:
- People you interact with frequently tell you to not to do it.
- Not having all the skills to execute what you want to do well.
- Asking people for help feels embarrassing and/or is annoying to them.
- The fear of having your work judged by others.
- Losing the "safety" that part of, or all of, your current income offers; especially if you have dependents.
For most people (in the context of what you said), those aren't really good reasons—it's just because it's difficult to leave the comfort zone (nothing wrong with that) because that will require at least some degree of readjustment that seem "risky". With that mindset it's actually very difficult to ever find a good time to do what you _want_ to do because all opportunities appear to be risks instead.
On a somewhat related note, I think it's important to just do what you think is fun and show it to the world, but turning that into something that you can make a living with is an entirely different challenge.
Most people don't actually get to do what they love doing for a living; even if you do, having the pressure that is the expectations of paying customers and/or maintaining revenue could take that love away from you. That's absolutely not to say that you shouldn't—it's just something that's good to be aware of before you jump into it.
I normally phrase this in a much more negative way: a "framework" is simply a "library" that does not place nice with others. It's good to hear a sensible positive phrasing for once.
It is a joy to use such a rich and well thought out Framework that really does do 99% of everything you need. Adding in your own stuff is about the easiest development I've ever done, and it just works. It was magic, and I miss using it.
My ideal framework is a library or set of cooperating libraries on the inside, with as little framework as possible.
e.g. Qt is a framework. Qt "calls you". But you can run the QPainter code without starting the Qt event loop or thinking too hard about QObjects. You should ideally be able to use the event loop without buying into signals and slots, though it won't be as ergonomic.
It's not always possible, it's not always worth it, but everything else being equal, I'd rather have no framework at all.
(For game engines I understand why a little framework is necessary - When you're talking about compiling to a weirdo platform like phones or consoles, the engine must also be involved in your build process and sometimes even libc shit. So you can't just make a Win32 exe that is a PlayStation game.)
But if we're modifying things like that, then they might as well make use of Nigel Tao's improved QOIR format, and replace the LZ4 compressor it uses with zstd. That's probably faster and likely compresses better than QOI.
Out of respect for your player's battery life, perhaps :)
In the (toy) web server I'm writing I initially also started with arenas. However I quickly realized that I don't actually need to grow and shrink memory at all.
Currently I'm simply allocating the memory I need up front then slice it up into pieces for every module.
When we're programming, we often pretend like we could be needing arbitrary amounts of memory, but that's not necessarily the case.
Many things actually have very clear limits. For the rest one can often define them. And if you enumerate those, you know how much memory you will need.
It is fun to think about and define those limits up front. It builds a lot of confidence and promotes a healthy frugality.
But it is very frequently possible to find the actual maximum you will need, allocate that upfront, and everything's great.
But when I realized that if I wouldn't allocate a large enough backing array (capacity) then memory would grow by n+(n+1)+(n+2)... every time I allocate on the arena during a request.
Now you're right that this is not necessarily a problem. But this is a side project that I just write in order to learn and explore stuff.
So I thought I would need to figure out a static capacity and was thinking about how to go about this. Then I realized I don't need a data structure that grows, but only a slice of a static memory region, which then means I don't need an arena (which can arbitrarily grow) in the first place.
Now I'm exploring all kinds of things that a web server does and where I would normally use a dynamically growable data structure. Like parsing JSON, form parameters, HTTP headers etc. And I can find natural or self imposed limits for all of those things.
For me, the most interesting thing about this isn't even performance. It's the mere fact that you _can_ figure out and design those limits. And the resulting code doesn't become complicated, but looks much simpler than I would have guessed. I really like the exactness of it all and how it changes the way I think about these things.
I still love futzing around in C...It was the original langauge I learned and God did I struggle with it for years. Like the OP mentioned, C is awesome because its such a concise language but you can go as deep as you like with it.
Thanks for all your efforts and the writeup...the game has a throwback Commander Keen-type vibe to it and I loved that franchise for a minute back in Carmack's pre-3D days.
From what I recall, what killed Flash wasn't iOS, but rather the acquisition of Macromedia by Adobe.
Chrome 45, in the name of performance, defaulted to only loading flash from 3rd party domains after a "click to load". This was bad for ads for obvious reasons, but it was much much worse due to an implementation detail.
In order to get the page laid out properly, Chrome loaded the flash component and then suspended it after a single frame. From an ad perspective, that was enough to trigger the impression pixel, signifying that the ad had been shown and the advertiser should be billed. However, the ad was not shown and there was no way for the ad to detect it had been suspended. Just a nightmare. We (I led the effort at BrightRoll) had to shift a ton of ad auction behavior to special case Chrome 45 and it limited what kind of ads we could serve.
That was the inflection point away from flash for ads. While ad formats like VPAID supported JS/HTML5, they didn't start getting popular until after Chrome 45 was released.
I've always wondered how ad companies verify the ad is actually being displayed. Can you explain this in more detail?
I imagine it has to be somewhat "bulletproof" since money is involved.
Are there new engines that are far better?
The JavaScript engine had a lot of workarounds for things that are not necessary anymore and some things that just don't work that well with modern browsers. From the top of my head:
- nearest neighbor scaling for pixel graphics wasn't possible, so images are scaled at load time pixel by pixel[1]. Resizing the canvas after the initial load wasn't possible with this. Reading pixels from an image was a total shit show too, when Apple decided to internally double the Canvas2D resolution for their “retina” devices, yet still reporting the un-doubled resolution[2].
- vendor prefixes EVERYWHERE. Remember those? Fun times. Impact had it's own mechanism to automatically resolve the canonical name[3]
- JS had no classes, so classes are implemented using some trickery[4]
- JS had no modules, so modules are implemented using some trickery[5]
- WebAudio wasn't a thing, so Impact used <Audio> which was never meant for low latency playback or multiple channels[6] and generally was extremely buggy[7]. WebAudio was supported in later Impact versions, but it's hacked in there. WebAudioContext unlocking however is not implemented correctly, because back then most browsers didn't need unlocking and there was no "official" mechanism for it (the canonical way now is ctx.resume() in a click handler). Also, browser vendors couldn't get their shit together so Impact needed to handle loading sounds in different formats. Oh wait, Apple _still_ does not fully support Vorbis or Opus 14 years later.
- WebGL wasn't a thing, so Impact used the Canvas2d API for rendering, which is _still_ magnitudes slower than WebGL.
- Touch input wasn't standardized and mobile support in general was an afterthought.
- I made some (in hindsight) weird choices like extending Number, Array and Object. Fun fact: Function.bind or Array.indexOf wasn't supported by all browsers, so Impact has polyfills for these.
- Weltmeister (the editor) is a big piece of spaghetti, because I didn't know what I was doing.
Of course all of these shortcomings are fixable. I actually have the source for “Impact2” doing all that with a completely new editor and bells and whistles. It was very close to release but I just couldn't push it over the finish line. I felt bad about this for a long time. I guess high_impact is my attempt for redemption :]
[1] https://github.com/phoboslab/Impact/blob/master/lib/impact/i...
[2] https://phoboslab.org/log/2012/09/drawing-pixels-is-hard
[3] https://github.com/phoboslab/Impact/blob/master/lib/impact/i...
[4] https://github.com/phoboslab/Impact/blob/master/lib/impact/i...
[5] https://github.com/phoboslab/Impact/blob/master/lib/impact/i...
[6] https://phoboslab.org/log/2011/03/multiple-channels-for-html...
[7] https://phoboslab.org/log/2011/03/the-state-of-html5-audio
Any chance you're going to release it, even if its incomplete?
In the end I switched back to JS/TS, because I found way more benefit from minimizing layers of abstraction and translation (WS is set up so you are forced to interface with JS to actually do anything), more than the benefits of any language or library.
(An exception might be something like Unity, due to the excellent featureset, but the IDE has become so slow it's unbearable...)
FYI - in non-fullscreen mode, on my Mac / Chrome, the bottom of the viewport is cut off. So can only play in fullscreen.
The game looks cool.
Weird, considering that JS is an even higher level language.
Years back I wrote a standalone Canvas2D implementation[1] that outperforms browsers by a lot. Sure, it's missing some features (e.g. text shadows), but I can't think of any reason for browser implementations needing to be _that_ slow.
This guy made billions illegally [2], and maintained the biggest ransomware crypto coin network for years, by offering the tools and SDKs to fund dozens of cyber war involved agencies across the planet. [3]
I have no idea how he got away with it, because his name keeps appearing in lots of crypto trading companies and trade registries. (Not gonna post them, but you can google his name to find this evidence)
He even organized a doxxing campaign against brian krebs at the time called "krebsistscheisse" via his pr0gramm platform [4] [5] [6], to somehow defend the idea that abusing user's computers for personal enrichment is a legit way of making money if you donate some low percentage to cancer research with it?!?
Sorry, but I would never trust this guy's code again. You should be careful, and audit any code he writes before you execute it.
[1] https://krebsonsecurity.com/2018/03/who-and-what-is-coinhive...
[2] 30% fee of monero/XMR went to coinhive: https://coinmarketcap.com/currencies/monero/
[2b] Schuerfstatistik on pr0gramm, where it all started: https://web.archive.org/web/20231005033135/https://pr0gramm....
[2c] Troyhunt analysis after he snatched away the coinhive TLD: https://web.archive.org/web/20240804081830/https://www.troyh...
[3] https://www.trendmicro.com/vinfo/us/security/news/cybercrime...
[3] https://krebsonsecurity.com/tag/dominic-szablewski/
[4] https://krebsonsecurity.com/2019/03/annual-protest-raises-25...
[5] (German) https://www.t-online.de/digital/aktuelles/id_83466874/tausen...
[6] https://www.heise.de/news/krebsistscheisse-Spendenwelle-an-K...
(Lots of other articles about it, and that dominic szlablewski was the guy behind coinhive, and the original owner of pr0gramm, while still doing development work for the company that owns the imageboard officially nowadays)
I've been meaning to write a proper post-morten about all that, now that the dust has settled. But in the meantime, just quickly:
- I did not make billions. You're off by quite a few orders of magnitude. After taxes it was well below $500k.
- Nothing I did was illegal; that's how I got away with it.
- Coinhive was not ransomware. It did not encode/hide/steal data. In fact, it did not collect any data. Coinhive was a JavaScript library that you could put on your website to mine Monero.
- I did not operate it for "years". I was responsible for Coinhive for a total of 6 month.
- I did not organize a doxing campaign. There was no doxing of Brian Krebs. I had nothing to do with the response on the image board. They were angry, because Brian Krebs doxed all the wrong people and their response was kindness: donating to cancer research. In German Krebs = cancer, hence the slogan “Krebs ist scheiße” - “cancer is shit”.
- Troy Hunt did not "snatch away" the coinhive domain. I offered it to him.
In conclusion: I was naive. I had the best intentions with Coinhive. I saw it as a privacy preserving alternative for ads.
People in the beta phase (on that image board) loved the idea to leave their browser window open for a few hours to gain access to premium features that you would have to buy otherwise. The miner was implemented on a separate page that clearly explained what's happening. The Coinhive API was expressly written with that purpose: attributing mined hashes to user IDs on your site. HN was very positive about it, too[1]
The whole thing fell apart when website owners put the miner on their page without telling users. And further, when the script kiddies installed it on websites that they did not own. I utterly failed to prevent embedding on hacked websites and educating legitimate website owners on “the right way” to use it.
I only have access to the trade volume of coinhive's wallet addresses that were publicly known at the time and what the blockchain provides as information about that. How much money RF or SK or MM made compared to you is debatable. But as you were a shareholder of the company/companies behind it, it's reasonable to assume you've got at least a fair share of their revenue.
If you want me to pull out a copy of the financial statements, I can do so. But it's against HN's guidelines so I'm asking for your permission first to disprove your statement.
> Nothing I did was illegal (...) Coinhive was not ransomware
At the time, it went quickly into being the 6th most common miner on the planet, and primarily (> 99% of the transaction volume) being used in malware.
It was well known before you created coinhive, and it was known during and after. Malpedia entries should get you started [1] [2] but I've added lots of news sources, including German media from that time frame, just for the sake of argument [3] [4] [5] [6] [7] [8]
----------
I've posted troyhunt's analysis because it demonstrates how easily this could've been prevented. A simple correlation between Referer/Domain headers or URLs and the tokens would've been enough to figure out that a threat actor from China that distributes malware very likely does not own an .edu or .gov website in the US, and neither SCADA systems.
As there was a financial benefit on your side and no damage payments to any of the affected parties, and none revoked transactions from malicious actors, I'd be right to assume the unethical motivation behind it.
> I did not organize a doxing campaign. There was no doxing of Brian Krebs.
As I know that you're still an admin on pr0gramm as the cha0s user, that's pretty much a useless archive link.
Nevertheless I don't think that you can say "There was no doxing of Brian Krebs" when you can search for "brian krebs hurensohn" on pr0gramm, still, today, with posts that have not been deleted, and still have his face with a big fat "Hurensohn" stamp on it. [9]
As I wrote in another comment, I also said that there are also nice admins on the imageboard like Gamb, and that they successfully turned around that doxxing attempt into something meaningful.
> I don't know what your personal agenda is, but there's so much misinformation and hyperbole in your comment that I have to assume that this is personal for some reason!?
This is not personal for me, at all. But I've observed what was going on and I could not be silent about the unethical things that you built in the past.
To me, doing that lost all trust and good faith in you. The damage that you caused on a global scale with your product coinhive far exceeds whatever one person's lifetime can make up for. And I think that people should know about that before they execute your code and are going to be a victim to a fraudulent coin mining scheme.
Calling this hyperbole and misinformation is kind of ridiculous, given that antivirus signatures and everything are easily discoverable with the term "coinhive". It's not like it's a secret or made up or something.
----------
[1] https://malpedia.caad.fkie.fraunhofer.de/details/win.coinmin...
[2] https://malpedia.caad.fkie.fraunhofer.de/details/win.monero_...
[3] https://cyberexperts.com/what-is-coinhive-malware/
[4] https://censys.com/de/hunting-for-threats-coinhive-cryptocur...
[5] https://www.pcrisk.de/ratgeber-zum-entfernen/8716-coinhive-v...
[6] https://www.golem.de/news/kryptomining-coinhive-skripte-warn...
[7] https://www.malwarebytes.com/blog/detections/coinhive-com
[8] https://www.coindesk.com/tag/coinhive/
[9] https://pr0gramm.com/top/brian%20krebs%20hurensohn
----------
Which of these sources is about the doxxing campaign? Or about making billions for that matter? And what kind of billions, monero or $?
If you google "doxxing brian krebs pr0gramm" you will find lots of other news sources, same as for "coinhive trade volume", as it was the platform that made monero/XMR the biggest cryptojacking platform.
Couldn't find anything to support the claim that he would have tried to dox Krebs. Also "maintaining biggest ransomware crypto coin network" feels like a dishonest phrasing trying to make it sound like he had something to do with ransomware. Monero was practically never used for ransomware payments back when coinhive was active, and even today Bitcoin is the most used method for ransom payments by far. Monero was simply the most profitable coin to mine with CPU.
That being said I agree that I wouldn't trust any software made by this guy. Even the hidden miner was obviously highly unethical and probably illegal.
This is a kind of wrong assumption. While I agree that ransomware payments themselves weren't done via monero or coinhive - malware on the other hand (read as: installed viruses/trojans/programs that the owner of the machine didn't consent to) was using it primarily to mine crypto coins.
See [3] from my previous post:
https://www.trendmicro.com/vinfo/us/security/news/cybercrime...
j/k :D
e.g. https://killedbyapixel.github.io/LittleJS/examples/stress/
https://github.com/phoboslab/high_impact#libraries-used
yep. exactly why I dont use C anymore. the package management story is so bad/non existent, that the typical approach is to just vendor everything. no thanks.