Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

1369558 Posts in 64360 Topics- by 56379 Members - Latest Member: ProdByAaronP

November 21, 2019, 03:37:14 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperPlaytestingThe Digit Dilemma - "Kind of a mix of Sokoban and 2048" - Play in browser!
Pages: [1] 2
Print
Author Topic: The Digit Dilemma - "Kind of a mix of Sokoban and 2048" - Play in browser!  (Read 777 times)
FrankForce
Level 2
**


This tepid water is tasteless.


View Profile WWW
« on: March 22, 2019, 07:16:22 AM »

Hi everyone,

I've had this idea in the back of my mind for over 20 years and it feels good to finally get it out. It is somewhat based on a TI-82 game I made a long time ago, and that game was based on an old game called "Darwin's Dilemma". I have added some new twists and really good procedural level generation.

This is an early prototype but I think this game concept has legs. The random level generation is already working really nicely. It generates solvable levels that gradually increase in difficulty. They may seem easy at first but trust me, they start getting surprisingly tough. In fact, it gets so hard that I actually made a whole feature that shows how to solve the puzzles!

The levels will continue forever though they get more complex and there are new mechanics introduced at level 10, 20 and 30 for anyone that gets that far. You can also go down a level, and when you do, some new options open up.

Anyway, I could really use some help testing it and feedback. Also does it get too difficult too fast? So far I've only gotten to level 20.

http://digitdilemma.3d2k.com


« Last Edit: March 23, 2019, 11:27:46 PM by FrankForce » Logged
JobLeonard
Level 10
*****



View Profile
« Reply #1 on: March 23, 2019, 11:27:14 AM »

Took me a moment to get it, but I agree it is a very elegant concept. Kind of a mix of Sokoban and 2048.

Twenty years, for real? Wow
Logged
FrankForce
Level 2
**


This tepid water is tasteless.


View Profile WWW
« Reply #2 on: March 23, 2019, 11:24:13 PM »

Thanks! That is a really good description of it.

So, I made a proto version of this game for ti82 in highschool. Since then I sometimes thought about remaking it. Recently though I had a really good idea about how to generate the levels and it all came together. Still trying to figure how to better craft the game around the core mechanics.
Logged
JobLeonard
Level 10
*****



View Profile
« Reply #3 on: March 24, 2019, 07:09:34 AM »

Is pushing the numbers into the walls supposed to break the walls, by the way?

Also, I wondered if you used something like rot.js, but looking at the source of the page I see a bunch of minified code and it's really tiny. Did you write this in raw JS yourself?
Logged
FrankForce
Level 2
**


This tepid water is tasteless.


View Profile WWW
« Reply #4 on: March 24, 2019, 08:24:48 AM »

Pushing numbers into the wall is supposed to happen. I originally had it so walls block the numbers, but it actually makes the puzzles much easier because you can use the wall as way of sliding numbers together. So I made the walls kind of a trap, like a soft failure. Then I realized I could mix things up by putting some random wall pieces inside the puzzle too.

The code is written from scratch in javascript. I just ran it through a crusher to obfuscate it a bit.

If you'd like to see somewhat cleaner code, I actually released a minfinied version for JS1k, and shared the pre-minified code for it: https://js1k.com/2019-x/demo/4180
Logged
-Coda-
Level 0
*


View Profile WWW
« Reply #5 on: March 25, 2019, 03:15:31 AM »

this mecanic is really clean i like it a lot, i think the evolution of the difficulty is fine the random level generator work well but i think i would prefer that the levels were handmade to compare my progression with my friends,and i found this bug, but overall its really good i want to see where this goes

« Last Edit: March 25, 2019, 03:24:56 AM by -Coda- » Logged
JobLeonard
Level 10
*****



View Profile
« Reply #6 on: March 25, 2019, 12:18:48 PM »

Quote
i think i would prefer that the levels were handmade to compare my progression with my friends
If we could save the random seed for each generated level and store that in the URL, we could have it both: randomly generated but reproducable levels that can be shared with others.
Logged
FrankForce
Level 2
**


This tepid water is tasteless.


View Profile WWW
« Reply #7 on: March 27, 2019, 08:34:36 AM »

Coda, thanks for the bug report! It's hard to tell from the gif what happened. Are you saying you think it generated an unsolvable puzzle?

Jon, I definitely want to add random number seed stuff soon. That would also help if someone thinks a puzzle is unsolvable.
Logged
-Coda-
Level 0
*


View Profile WWW
« Reply #8 on: March 28, 2019, 08:53:04 AM »

in fact this happend when i press the down and right button at the same time (I'm sorry I didn't specify)
Logged
FrankForce
Level 2
**


This tepid water is tasteless.


View Profile WWW
« Reply #9 on: March 30, 2019, 03:18:14 PM »

Oh wow thanks! That's an awesome bug that I didn't know about.

It doesn't really break the game though, so lets just call it a feature for now Wink
Logged
AoF
Level 0
**



View Profile WWW
« Reply #10 on: April 05, 2019, 12:49:34 PM »

The levels will continue forever though they get more complex and there are new mechanics introduced at level 10, 20 and 30 for anyone that gets that far. You can also go down a level, and when you do, some new options open up.

I appreciate knowing this before I play.  Thank you.

Quote
Anyway, I could really use some help testing it and feedback. Also does it get too difficult too fast? So far I've only gotten to level 20.

On the first screen, I have no idea what I'm supposed to do/press to start the level.

Oh, this is the level.  I thought it was a tutorial page.

That first level ends so abruptly, it made me feel like I'm not sure how I did it.  Apparently I did the right thing, though.

After pushing the 2s together on the 2nd level, I get how to play now.

Or... I thought I did.  Apparently, the numbers slide all the way across when you push.  I thought they went one step at a time.

Yeah, this game is pretty cool.  I'm at level 4.  At level 3, I had to experiment and undo to figure out some of the rules.

The main thing I want right now is for the game to freeze after I beat a level and let me press something to continue.  I want to see and relish in my victory for a bit. 

OK, apparently I can push things INTO the walls.  I'm on level 6.  I don't know if I can still merge things if they're in walls or if that freezes them.  I want to restart this level.  Maybe that's what "Level down" does, but pressing '-' is not doing anything.

Level 6 was the most challenging level for me so far.  Pushing through walls is not something that I would have assumed could be a strategy.  What I really want is a R button to restart.

Level 7 was easier than 6.

Level 9 seemed so complex, that all I could do was try stuff and hope that it worked out in the end.  I beat it on my first try, but it was the first time it didn't feel "awesome."  I felt like I got lucky and didn't earn that win.  There were too many steps to think ahead than I could personally plan for so I just tried anything.

Level 10 gave me a little bit of that feeling near the end, but not as much as 9 did.

Ah, ok, so "Minus - Level Down" is not a keyboard instruction. 

Level 11 seems too hard to me and this is where I'm going to quit.  That minus block adds too many possibilities in my mind.  What I suggest you do is make Level 11 really straight forward with the minus block before you give me so many options for it.  But then again, maybe it could be just a bad concept?  The minus block's existence makes me feel like I could have made a mistake on ANY step, and I'll just have to wait until I get stuck to realize that I did.  The thought of that happening is so un-fun, I don't want to experiment on this level to figure out how to beat it. 

I hope this feedback was helpful.  I could really use some feedback on my game, too.  Note it's slightly NSFW: https://forums.tigsource.com/index.php?topic=67183.0

Logged
JobLeonard
Level 10
*****



View Profile
« Reply #11 on: April 05, 2019, 01:40:13 PM »

Did you notice you can undo your moves step by step, and rewind all the way to the start of the level?
Logged
AoF
Level 0
**



View Profile WWW
« Reply #12 on: April 05, 2019, 01:52:29 PM »

Me?  Yes, I did.  I still want to be able to restart from a single key press. 
Logged
JobLeonard
Level 10
*****



View Profile
« Reply #13 on: April 06, 2019, 12:44:50 AM »

Ah, like that! Yeah, I agree that that is more convenient.

I was just worried that you didn't know you could soft-reset that way and was frustrated because you were stuck, so I wanted to make sure you wouldn't be Smiley
« Last Edit: April 06, 2019, 01:51:47 AM by JobLeonard » Logged
AoF
Level 0
**



View Profile WWW
« Reply #14 on: April 06, 2019, 01:02:38 AM »

Ah, like that! Yeah that is more convenient.

I was just worried that you didn't know you could soft-reset that way and was frustrated because you were stuck

Ah, naw.  I used it a lot actually.
Logged
a-k-
Level 0
***


View Profile
« Reply #15 on: April 06, 2019, 03:15:59 AM »

This is very interesting. Just by repeatedly -/+'ing to the same level multiple times, I couldn't tell acccording to what criteria you graded the levels.
Logged

JobLeonard
Level 10
*****



View Profile
« Reply #16 on: April 06, 2019, 05:18:19 AM »

@AoF: Hand Thumbs Up Left

@FrankForce: So, epic feedback incoming.

First, I would like to report a performance bug and suggest some ways to solve it:



Looking at the source code, the reason is pretty clear to me: you rebuild the entire webpage every iteration of the game-loop, which currently tries to refresh every 16 milliseconds. I guess that it's due to the JS1K origin, but a tilemapper that marks dirty tiles and only updates those nodes that have to is much faster. Also, you can really shrink your HTML code a lot. Currently, the individual tiles are made like so:

Code:
<font color="#000"><span style="background-color: #FFF">#</span></font>

You don't need the font, since you already set the font family on a global level, and less nodes would mean less reflow calculations. And individual styles take more CSS calculations than shared classes IIRC, so define the latter with color and background-color, and you can reduce that to:

Code:
<span id="tile_0_0" class="wall">#</span>

As for the tilemapper, here's what I would suggest: render level as a whole once, and give each tile a unique id, i.e. <span class="wall" id="tile_0_0">#</span> for the top left wall piece. Then initiate an array that stores the element for each tile:
Code:
var tileElements = []
for(y = 0; y < size; y++)
for(x = 0; x < size; x++)
{
    tileElements.push(document.getElementById("tile_" + x + "_" + y));
}

In the loop where you currently rebuild the whole website, instead check if the tile is "dirty", and if so change only that tile:

Code:
if(anyDirty) { // only rerender if any tiles need updating

  for(y = 0; y < size; y++) {
    for(x = 0; x < size; x++) {
      // assumes tileNeedsUpdating is an array matching layout of tileElements,
      // and that it is set to true if the game logic determined that it needs to change
      if (tileNeedsUpdateing[size*y+x]) {
        switch(playArea[size*y+x])
          /* ... */
          case -1:
            // make sure the unique id is correct
            var tileId = "tile_" + x + "_" + y;
            // update only this tile
            tileElements[x + y.size].outerHTML = "<span class=\"wall\" id=\"" + tileId + "\">#</span>";
            break;
          case  0:
          /* ... */
          default:
            isWrong = (wrongNumbers.indexOf(v) > -1);
        }
        // Mark that tile is no longer dirty
        tileNeedsUpdating[size*y+x] = false;
      }
    }
  }
  // done updating
  anyDirty = false;
}

Because honestly, currently the game never updates more than two tiles at a time so this saves a lot of DOM rerendering time.

Regarding the game loop, you're currently using setInterval(GameLoop,16). I would suggest using David Baron's zero-delay setTimeOut-alternative instead, like so:

Code:
   // Only add setZeroTimeout to the window object, and hide everything
    // else in a closure.
    (function() {
        var timeouts = [];
        var messageName = "zero-timeout-message";

        // Like setTimeout, but only takes a function argument.  There's
        // no time argument (always zero) and no arguments (you have to
        // use a closure).
        function setZeroTimeout(fn) {
            timeouts.push(fn);
            window.postMessage(messageName, "*");
        }

        function handleMessage(event) {
            if (event.source == window && event.data == messageName) {
                event.stopPropagation();
                if (timeouts.length > 0) {
                    var fn = timeouts.shift();
                    fn();
                }
            }
        }

        window.addEventListener("message", handleMessage, true);

        // Add the one thing we want added to the window object.
        window.setZeroTimeout = setZeroTimeout;
    })();

    var runGameLoop = (function() {
        // prevent possibility of starting multiple game loops,
        // and allows pausing the loop by calling runGameLoop(false)
        var isRunning = false;
        var actualLoop = function() {
            if (isRunning){
                GameLoop();
                window.setZeroTimeOut(actualLoop, 16);
            }
        };
        return function(start) {
            if ((start || start === undefined) && !isRunning) {
                isRunning = true;
                window.setZeroTimeOut(actualLoop, 0);
            } else if (isRunning && start === false) {
                isRunning = false;
            }
        }
    })();
    

Not that this game will likely have a lot of jank, but IIRC setInterval queues up missed events - setTimeOut more elegantly handles low framerates :p. More importantly, this loop can be paused/resumed at will. With that you can limit the times the game loop actually runs to whenever the player pushes a key, which lets the CPU idle when not being used, which saves battery power.


To do so, strip out all input event-based logic from the game loop (so for key presses or touch input) and make those their own separate events that react to input. If they are triggered, they should modify a global input object and start the game loop (if it isn't running yet). The game loop is started with setTimeOut, so it only starts after the input events are finished. The game loop then looks at the state of the input object, reacts accordingly, and starts rendering. Once all animations are done (and assuming no new inputs were triggered in the mean time) it can pause itself again.

This removes the need for running the game 60 frames a second if no inputs exist, the latter of which is kind of the default for this game.

Now, maybe you were planning to animate the game more but then I would suggest using a canvas element to avoid all the DOM updates.

Also, once the performance issues are fixed, one really nice nice-to-have would be making the website off-line first. It might seem like total overkill for a game this tiny, but the ting is that this is the kind of coffee-break game I would play on a train trip with no internet (assuming that perf bug is fixed), plus it doesn't need to fetch new content most of the time anyway so that would it a lot easier to support. It's just one static page, so adding AppCache (for older browsers) is trivial for once. For Service Workers the Cache/Update/Refresh method seems like a good fit (you get served the static page immediately, and a notification if a new version is available).

I had some UX ideas too, but there's a lot of personal preference in there as well so if you disagree I totally get that (although I'm generally interested in your motivation for your design choices so I would still like to hear why in that case):

- I have a touch-screen on my laptop but it's not visible that the game has touch input; I only noticed after opening the dev tools. Similarly, sometimes people use bluetooth keyboards on android tablets and that input should still work. So why not show both sets of instructions together all the time?

- Making the "hitboxes" for the touch edges visible somehow (like with background divs that have a slightly different color, although that doesn't look good in my mind) might also improve the UX, because I was a bit confused at first when the character moves.

- Alternatively, how about four old-school <button elements, laid out below the level tiles, and give them large styling for tap-friendliness? When done right that also might make the website more accessible for people with disabilities, since they can tab/activate through the buttons! Would also allow for level down and undo support on mobile. Alternatively, you could use old-school box-drawing characters (see mock-up below)

- Regarding graphics: how about using CSS letter-spacing to make the tiles square? Here's what it looks like (I used the dev tools to manually override the whole body). It doesn't seem to be supported on mobile, and the letters are left-aligned which looks a bit odd, but it looks nice on the desktop, especially if the numbers get a suble background coloring to make them more clearly square-shaped:



I actually made two mock-up static HTML pages, one like the above, one for a two-thumb portrait mode:

https://blindedcyclops.neocities.org/digit-dilemma-mockup1.html
https://blindedcyclops.neocities.org/digit-dilemma-mockup2.html
« Last Edit: April 06, 2019, 05:23:38 AM by JobLeonard » Logged
FrankForce
Level 2
**


This tepid water is tasteless.


View Profile WWW
« Reply #17 on: April 09, 2019, 06:57:26 AM »

Hey JobLeonard and AoF! Amazing feedback thank you so much! It was super helpful reading your actual thoughts playing through the game at first.

You can push - to go down a level. I realize now it probably didn't work for you because you were pushing the - on the number row and not the keypad. I will make both work.

I'll add press R to restart!

I think I kind agree about the - block. It does make it much harder when one is there. You can actually count up the numbers and do some math to figure which number it must have come from. So I am thinking maybe it would be make sense to highlight numbers that don't add up properly. The plus block is even tougher because suddenly numbers can also go up.

I didn't realize it was performing so poorly. I figured the draw was super slow the way I'm doing it now. Excellent suggestions for optimization. I need to brush at css asap.

The square lettering looks real nice (: Nice touch pad mockup, I think it's a great idea. For design of this game I was going with a super minimalist approach, let the player discover things, but I probably went a bit too far. You're mockup looks great though, it fits the theme perfectly.

I am juggling a bunch of projects right now but I'd like to get back to this one soon. The main thing I'm trying to decide on now is what to do about difficulty. It just keeps getting harder until the player gives up, pretty harsh! Once I figure out what to do with that I'll do another pass on it. Thanks again for all the great feedback!
Logged
Eyon
Level 2
**



View Profile
« Reply #18 on: November 01, 2019, 05:40:49 AM »

Hello! I managed to get to level 10! =]
It's nice. Maybe a button to start over would be good instead of having to click repetitively on the space button.
Logged

michaelplzno
Level 4
****



View Profile WWW
« Reply #19 on: November 01, 2019, 01:55:25 PM »

This is a lovely concept and well executed. I'm a bit burnt out on this kind of logic puzzle because just as the levels can be procedurally generated, the solutions are also not that complex to automate as well. Keep at it!
Logged

Pages: [1] 2
Print
Jump to:  

Theme orange-lt created by panic