Joel Thoms
Gamedev, JavaScript, ReactJS, and Node

Follow

Gamedev, JavaScript, ReactJS, and Node

Follow
Dungeon Sweeper: A Knight's Adventure -- devlog 004

Dungeon Sweeper: A Knight's Adventure -- devlog 004

Joel Thoms's photo
Joel Thoms
ยทApr 20, 2023ยท

6 min read

TL;DR: I discuss adding intuitive features, dealing with Phaser quirks such as a tween memory leak and scaling issues, managing screen size, and creating an executable for a demo. I express my struggle with the less enjoyable parts of game development but remain motivated to push out a demo.

Name Change

I think I like the name Dungeon Sweeper: A Knight's Adventure more than Dungeon Sweep: Knight. Sure, it's a bit longer, but it's also more descriptive of what it is. The game is based on Minesweeper, So I think keeping Sweeper (as opposed to Sweep) in the name makes sense. Let me know what you think in the comments!

Giving The User What They Want

I watched a handful of people play my game and I kept giving the same instructions, "You can't drag to scroll, you have to click a tile to move to that spot."

I would repeat those instructions multiple times to the same players over and over again. They couldn't help but try to scroll the screen.

I decided to stop fighting it. If their intuition was to scroll, then I needed to add that feature.

A game that is intuitive to the user is better than forcing my way. It turns out I love the mechanic and it was worth the added time to get it into the game.

I'm Struggling with Phaser

In the beginning, Phaser was a breeze, but I'm running into a bunch of little quirks that are slowing me down.

Tween Memory Leak

I have a tween set to repeat: -1 (loop infinitely) and the target Sprite is destroyed, the tween remains. This is effectively a memory leak. I assumed Phaser was smart enough to kill the tween when the target is destroyed (Phaser does this for non-infinite Tweens). To work around this I have this block of code:

// tween must be manuall removed when sprite is destroyed
sprite.once("destroy", () => {
  scene.tweens.remove(tween);
});

My Zoom / Scale Mistakes

The pixel art I am using is 16x16 and I am scaling this up 2.5x to 40x40. In Phaser, it's really easy to set the camera zoom.

camera.setZoom(scale);

I was really happy with this early on since the camera did all the work for me. I'm paying for this mistake now.

All positioning now needs to be calculated with this scale in mind. Dragging was complex because the pixels you drag vs the pixels that must move are affected by the scale.

// Update X position of score text
score.setX(scene.cameras.main.width / scale);

// Actual distance ondrag needs to be scaled down to match finger
let diffX = Math.round(pointer.x - pointer.downX) / scale;
let diffY = Math.round(pointer.y - pointer.downY) / scale;

I could have eliminated this scale complexity by manually upscaling all my assets and using a zoom of 1:1.

Scroll on Drag Sucks

Something so simple and so complicated. The scale did not help with this either.

Because Phaser's camera is following a Sprite, I decided to modify the camera.scale.followOffset to move the screen. I'm not sure if this is the best way.

But found I had to keep saving the followOffset in my global state to run the math.

// ๐Ÿ˜ฅ Math is getting complicated for a simple scroll on drag

const diffX = Math.round(pointer.x - pointer.downX) / scale;
const diffY = Math.round(pointer.y - pointer.downY) / scale;

const offsetX = states.drag.followOffsetX + diffX;
const offsetY = states.drag.followOffsetY + diffY;

camera.setFollowOffset(offsetX, offsetY);

Overscrolling? So if you drag too far and hit the bounds I have set, the camera stops scrolling, which is what I want to happen. But the numbers keep going up in the followOffset. This means the user has to drag back to the visible area before the screen starts to animate again. It's kinda like a dead zone.

After I figured that out, I had to do even more math to limit the followOffset to the bounds set on the camera.

scene.input.addListener("dragend", () => {
    const knight = gameState.sprites["knight"];
    const distX = knight.x - camera.worldView.centerX;
    const distY = knight.y - camera.worldView.centerY;

    // this is needed to prevent overshooting the offset
    camera.setFollowOffset(distX, distY);
});

Fit to Screen

I ended up having problems using Phaser's fit-to-screen feature. It worked on Chrome and Android but had issues on iPhone. So now I am managing the screen size myself. I am not sure if this is the best way. Let me know in the comments.

// Phaser's fit-to-screen didn't work for me. So let's manually do it.
window.addEventListener("resize", () => {
  const { game } = gameState;
  game.scale.resize(
    document.body.clientWidth,
    document.body.clientHeight
  );
});

I'm Not Having Fun

So I'm into the part of the Game Dev that is simply not fun. I am trying to push out a demo so people can try it and provide feedback. But there are a few steps to take that I'm not enjoying one bit.

Creating an Executable

I need to create a "build". It's a simple HTML / JavaScript game so I guess I'll package this up with Electron. Electron seems popular, so sure let's use that. Well, Electron has turned my 1MB JS bundle into a 100MB exe. But hey, at least it's an executable.

Is there an alternative to Electron I can use? Help!

Code Signing Nightmares

Electron suggests Code Signing the executables. I looked into this and it's too expensive for what I am making. Everything requires an annual fee. Rough estimates on the low end of this are around $200/year.

I got excited when I found Fulcio a free Code Signing option but after wasting half a day on this, I found this line in the GitHub, "Fulcio only issues short-lived certificates that are valid for 10 minutes."

It's that 10 minutes part that makes this option unusable for me. Honestly, I am not sure what I could use this for with that short life.

I may just end up doing Android / iPhone (and no Windows / Mac / Linux), which does have some costs too, but I have already accepted this cost mentally before starting the project.

Or maybe I'll provide executables with no Code Signature. I don't know what the impact of that will be.

What are others doing? Is Code Signing that important? I don't know.

Marketing

Let me start by saying I probably couldn't be doing any worse than I am right now in this department. But what can I do?

I need a page to send people to. I have nothing right now. So I'm putting all my focus into getting a Demo live. I'm planning on getting this on itch.io. The problem with itch.io is they recommend having it as "close to ready" as possible and I need to set a price to charge. That's complicated since it's still in development.

But I have found a good compromise. I can set a price, and also provide a demo for free. So that way people can get the demo.

I thought of having two itch pages, one for the demo and then when ready, another for the paid game. I don't know the itch etiquette or how others handle this.

If you know, let me know!

Demo Soon!

Well, the demo is coming very soon! If you don't want to miss it, toss your name into that Newsletter box at the bottom. See you soon! Cheers ๐Ÿป

ย 
Share this