30 comments

[ 3.4 ms ] story [ 71.2 ms ] thread
I was hoping this could be used to gamify things, but this is basically a clicker, yes?
The name may not be familiar to everyone, but I believe tthats what idle games in the title refers to, i think.
Yeah. Clicker, idle game, incremental game. I combine them all into the same genre in my head.
Idle games usually go automatic after a while, as in you can unlock things that click themselves after a while. It's a great model for gamification though!

I haven't looked into it enough to see whether it's an idle or incremental game. Incremental games usually unlock some entirely new game mechanic after a certain stage.

Merchant is used mainly to handle large amounts of number changes in a way that makes sense. In a lot of games (especially idle games), there's lots of different counters that should be updated all at once.

For example, you may have the amount of player gold and experience, but you also might have a number for every item in the game. Merchant is a pattern to deal with all of these in one fell swoop instead of having lots of separate functions that loosely relate to each other like:

``` updateGold(); updateSwordPower(); payForSwords(); ... ```

So it could be used in gamification if you have lots of currencies and items, yes. But if you're doing something simple, you might be better off just doing it with regular javascript patterns.

This is really nice. I'd love to make one for native mobile some day.
Thanks <3

I fully recommend building one! Idle games are a fantastic programming zen exercise.

They're incredibly state-focused rather than UI focused, which means the hard parts are typically creating the systems rather than dealing with weird css quirks. For the same reason they're really easy to test so if you've ever been itching to try out some pure test driven development, an idle game might be a good place to start.

Why Map is used instead of plain object {} ? And why it's Map and not new Map ?
Because their Map type is not the JavaScript Map type but immutable.Map.
I've recently been playing a fascinatingly complex mobile incremental/idle game called Almost a Hero [0] by Bee Square Games, and as a case study in game design, it's rather fascinating to think about how the developers must have implemented the game logic to result in the reliable behavior the game exhibits.

While OP's framework is well-suited to an online idle game, in which you can count on a constant thread modifying ledgers on a timeout, one of the constraints for (well-made) mobile idle games is that there should be progression while the user is offline. Almost A Hero's devs took this all the way to the craziest conclusion; you don't just accumulate predictable "gift boxes" while offline, your characters actually simulate live gameplay at an accelerated rate when you next start the game, with dozens of simultaneous powerups interacting in nonlinear ways at any given time all simulated to give an accurate account of loot you would have gained had you had the app open for that time. So if you wanted to run an accurate offline simulation of the game logic, you could either store timestamps of historical, immutable events and try to derive things mathematically... or you could step frame by frame, and keep running ledgers, but you'd need to ensure that you can tick the frames based on arbitrary fractional units of time, i.e. if you have a powerup that's exactly 1.5 seconds long you wouldn't want to just round that to the nearest 1FPS frame, nor would you want to do the simulation at 60FPS when a user might have been offline for hours.

And that's just the game logic; if you actually want to animate character movement based on these values, you also need to manage declarative rendering i.e. "because I began my most recent weapon swing at time T-3, paint sprite X at time T."

All of these interactions are at play in AAH, and it's led to remarkably complex gameplay with a delightfully positive min-maxing strategy community [1].

So, returning to OP's framework, I'd encourage folks thinking about this problem to take time management into consideration as something a good idle game framework should help developers to build. It's a fun problem space to innovate in!

[0] https://itunes.apple.com/us/app/almost-a-hero/id1116630619?m... / https://play.google.com/store/apps/details?id=com.beesquare....

[1] See, for instance, the guide here: https://www.reddit.com/r/AlmostAHero/comments/706k7n/almost_... ; there's an active Discord channel as well.

Not sure what your point is. You think it should be possible to run the simulation at increased speed?
I think the point is that they'd like to be able to simulate things that happen while the player is not on the page. So, save the state somewhere with a timestamp, and when re-hydrating it compute things that would have happened while they were gone.
Looks cool! Alternatively I found that Vue.js rather than React makes it really simple to handle these types of games (though you no longer have the immutability and history which can be useful for persistence). At last Ludum Dare, I quickly hacked one of those games (look at the source to see how compact it can be) http://aqua.gistnoesis.net/ld39.html .
You can use Redux with Vue as well, it isn't just restricted to React
That paperclip game is insanely addictive!
Are there similar games designed to be "hacked" with javascript in the console?
Candy Clicker is a great example. I miss 2013.
I don't know about being designed for it, but me and a few coworkers had a great Friday afternoon a year or two ago screwing around with http://zty.pe/
I might put a warning on it.
I've explored about 0.1% of the universe with 30 sexdecillion paperclips.
I like immutable objects. But my worry is it will lead to lots of small objects being created just to get destroyed right away, putting lots of pressure on GC. I wonder if this is a known issue in the immutable js community.
When you insert into an immutablejs collection, a copy is not made. It's reusing a reference to the old object. That means iteration is a bit slower while insertion and similar operations is faster, which is an acceptable tradeoff