Adopting the Linktree Convention to Redirect People to My Projects

Instagram only allows a single click-able URL in the profile. Most people seem to use a service called Linktree. To get a feeling for the format, here’s an example by Alicia Keys and one by the MoMa.

The styling is a bit different for each site. Some have photos, some have plain colors. But all have the same elements of the same size: a circular picture at the top, and a list of links as very wide buttons. It’s optimized for mobile use, to make you rstuf available for visitors of e.g. Instagram profiles.

I find the format interesting for this use. It’s a hub of central links. That’s useful if people discover you on social media but don’t yet know you. If I point people from my watercolor/sketching Instagram profile to this personal website of mine, christiantietze.de, they won’t see any picture, any drawing, but lots of stuff in English about “computers”. That’s not helpful.

So I built my own Linktree page: https://christiantietze.de/linktree/ – And the best of all: I can style it however ugly or pretty I want, add animations, sparkles, you name it, because it’s on my own website!

It’s a list of links, the style is optimized for mobile consumption as a menu, and there’s not much going on in general.

I also considered using my /now page for this, but it’s too wordy, and it’s designed to describe the current point in time, not provide a comprehensive overview of my stuff.

That being said, the Linktree format lends itself to use for evergreen links to redirect visitors to your blog, your social media profiles, and such things – but also to ever changing content, like “My latest album XYZ on Spotify”, which you’ll want to replace with your next album once that comes out.

Let’s see what happens with that link hub/menu/directory format.

This is a gentle reminder to everyone out there that hosting your own website is not that hard, and it is super rewarding because you have 100% control and don’t rely on external services to do the simplest things, like displaying links. (To be fair, Linktree offers a couple of built-in marketing features in the “Pro” tier when you look at their pricing page.)

Implement Pixel-by-Tile Movement in Godot

I found an answer in the community portal about grid-based movement, but they’re using tweens to animate. That’s an interesting approach, but I think it’s a bit too much of this modern day technology for my stomach.

Let’s dig out how we old people used to code 2D movement with our own hands. (That’s one tech dependency down, which is always good.)

What is Pixel-by-Tile Movement?

With the SNES as a reference, from that era you had access to these three top-down movement and animation techniques for tilemap based games:

  1. Tile-by-tile movement. That’s moving on a grid without animations. This is more like how Ultima 1 did it, or how ASCII characters would move on Terminal screens. Collision detection is simple: check all 8 surrounding tiles for obstacles.
  2. Pixel-by-tile movement. Characters move on the strict tile grid, but they animate their location changes. You could imagine it like this: each character has a position on the tile map, measured in coordinates like on a board of chess, and its sprite is drawn with a pixel-based offset relative to that position. Collision detection is as simple as before, it just looks prettier. This is the least you could do to make player eyes not hurt. Think Final Fantasy 2–5, or amazing QBasic clones as per ye olde tutorials. It’s what I’ll be showing here.
  3. Pixel-by-pixel movement. Think Zelda, Secret of Mana, Chrono Trigger, or most action platformers. The world might be created from a tile map, but the player sprite moves smoothly across the screen, often times even supporting diagonal (!!!) movement. Controls feel more responsive because you don’t issue a “move one tile” command and wait for the animation to finish. Instead, as soon as you press, the sprite moves, and as soon as you release the button, the sprite stops. Mind-blowing. But this also makes collision detection more complicated. (That doesn’t matter much in Godot.)

So movement on a tile-based grid with animation of the in-between steps is called “pixel-by-tile movement”. When you look on the web, it’s often referred to as “pixel-by-tile scrolling”, because camera or viewport movement was the most involved.

Restict Player Input and Animation Steps

The player sticks to the 16x16 grid and moves pixel-by-pixel between the steps

When you start out with Godot, most tutorials showcase direct player control and pixel-by-pixel movement. To get to tile-based movement, you need to add constraints to the modern Godot engine; that’s a bit awkward at first, I can imagine. It boils down to these simple steps:

  • Reject player input while the movement is in progress. Player movement is not direct anymore, but controlled by a simple state machine of a is_moving check. While the player is moving, ignore input; wait for completion of the last move command.
  • Count your steps. If your grid is 100px wide, and you want smooth movement, move the player 100 times by 1 pixel. If steps == 100, complete movement by setting is_moving = false.
  • Compute speed in pixels-per-second. If you want the player to move across the 100px cell in 2 seconds, the speed is 2 / 100 = 0.02. This is real-world time that needs to pass between each step.
  • Wait for between-step-time to pass. Godot’s engine uses the callbacks _process(delta: float) and _physics_process(delta: float). delta is measured in fraction of seconds since the last pass. The callbacks are invoked all the time, frame-independently. When we move at a speed of 0.02 pixels-per-second, we need to time movement to the second. To do that, we accumulate deltas (accumulator += delta) until we reach that threshold (accumulator > 0.02). If we do, animate the next step, move by 1px, and reset the timer (accumulator -= 0.02, to keep the overflow).

Also, scale up your game if needed. I set my sample to a resolution of 320x200, with a window size of 1024x700 (the default) and viewport scaling. This way, you get chunky pixels on screen. Positions are measured in pixels, too. If you don’t do it this way but scale your sprites up by a factor of, say, 10x, then the sprite will appear equally chunky on screen, but you can change its position to what appears to be 1/10th-pixels. It looks buttery smooth, but also not very fitting.

Implementation

Here’s a sample implementation for a tilemap grid of 16x16 pixels:

extends KinematicBody2D

const TILE_SIZE = 16

# Store the last input command's direction.
var direction: Vector2 = Vector2.ZERO

# Speed of movement
var _pixels_per_second: float = 2 * TILE_SIZE
var _step_size: float = 1 / _pixels_per_second 

# Accumulator of deltas, aka fractions of seconds, to time movement.
var _step: float = 0 

# Count movement progress in distinct integer steps
var _pixels_moved: int = 0

func is_moving() -> bool:
    return self.direction.x != 0 or self.direction.y != 0

func _physics_process(delta: float) -> void:
    if not is_moving(): return

    # delta is measured in fractions of seconds, so for a speed of
    # 4 pixels_per_second, we need to accumulate deltas until we
    # reach 1 / 4 = 0.25
    _step += delta
    if _step < _step_size: return

    # Move a pixel
    _step -= _step_size
    _pixels_moved += 1
    move_and_collide(direction)

    # Complete movement
    if _pixels_moved >= TILE_SIZE:
        direction = Vector2.ZERO
        _pixels_moved = 0
        _step = 0

func _input(event: InputEvent) -> void:
    # Set direction according to user input

You can put the same stuff in _process(delta: float) and use a simple Node2D (or Area2D if you care about collision callbacks). I like to get used to KinematicBody2D so I can use body_entered-based collision callbacks. If your player character is an Area2D, areas on the map would report area_entered, which reads more as if a wood is overlapping with a river than a character entering a zone.

Comparing 2D Collision Detection and Hit-Testing Approaches in Godot 3

I played around with Godot and found that when my player character moved too fast, it would not collect items in its path.

Here’s a short visual comparison of two approaches to move things in an engine like Godot. If you don’t know Godot: it is an engine, tool, and IDE to create cross-platform 2D and 3D games and GUIs. It’s basically Unity, but open source.

This is a classic hit test/collision detection problem. In the past, the game prototypes I programmed myself were rather simple and slow-paced, so I thankfully never encountered this problem before, because it requires a couple of tricks if you have to program the engine yourself.

Play the demo
Check out the code on GitHub

Using Area2D and manual hit detection

My naive approach in Godot was to make the player an Area2D with a collision shape and change its position according to player input. This combination will fire events (aka “signals” in Godot parlais) when other objects enter and leave the area. I got this approach from the “Your First Game” tutorial and was happy to roll with it as I initially found the plethora of 2D nodes I could select overwhelming.

The gap between initial position and next position is never checked with naive collision detection.

Here’s a simple back-of-the-envelope calculation to illustrate the problem: Your character starts at position (x=0, y=0). Say it’s 10x10 pixels large, and your collision detection uses this size relative to the position to see what the character is interacting with, so the covered rectangle is (min_x=0, min_y=0, max_x=10, max_y=10). You now move it to the right at a pace of 100 pixels per frame. In the next frame, the covered rectangle now is (min_x=100, min_y=0, max_x=110, max_y=10). That’s basically a jump. You skipped over the whole area from (x=11, y=0) up to and including (x=99, y=10).

That is how you can clip through walls, and walk over items or through enemies if your speed is too high.

Prevent clipping with KinematicBody2D and Godot’s physics engine

To prevent clipping in Godot, your next best bet is a KinematicBody2D. That’s a 2D shape that participates in Godot’s physics engine calculations. You can apparently get a lot of physics for free, like standing on platforms, sliding down slopes, and letting 2D boulders tumble down and collide with each other and propagate forces. A KinematicBody2D, though, only triggers the calculation callbacks – you have to implements the effects yourself. With a player character that should collect coins and not be deflected by them, this sounds like a good approach!

At regular speeds, nothing weird happens
At higher speeds, the KinematicBody2D area collision detection works like a charm while the Area2D approach already skipped a lot on the ground

The transition in code is rather straightforward, too. Instead of the _process callback on every tick, you hook onto the _physics_process callback and use the built-in movement methods to let the Engine do the rest.

Compare the traditional “just change the position” approach with Area2D

extends Area2D

# -1 for moving left, +1 for moving right
var velocity: float = 0

# Pixel per second
var speed: float = 100

# Built-in callback for key presses
func _input(event: InputEvent) -> void:    
    self.velocity = 0
    if Input.is_action_pressed("ui_right"):
        self.velocity = +1
    if Input.is_action_pressed("ui_left"):
        self.velocity = -1

# Built-in callback for every tick of the game loop.
# `delta` is the fraction of a second.
func _process(delta: float) -> void:
    self.position.x += self.velocity * self.speed * delta

… with a physics-based KinematicBody2D:

extends KinematicBody2D

var velocity: float = 0
var speed: float = 100

func _input(event: InputEvent) -> void:
    self.velocity = 0
    if Input.is_action_pressed("ui_right"):
        self.velocity.x = +1
    if Input.is_action_pressed("ui_left"):
        self.velocity.x = -1

# Built-in callback for physics processing, 
# run before the `_process` callback.
func _physics_process(delta: float) -> void:
    var velocity_vector = Vector2(self.velocity, 0)
    self.move_and_collide(velocity_vector * self.speed * delta)

Both approaches are quite short, and both share a lot of code. These are GDScript node scripts, each attached to a player node in Godot.

The move_and_collide method is described as such:

If the engine detects a collision anywhere along this vector, the body will immediately stop moving.

This is the crucial difference: the engine detects collision along this vector. So the whole space between start and finish is checked, basically.

With this approach, I found I don’t even need to make the coins physics-based objects, since the collision detection events are triggered in the same way.

In this video, you see how an Area2D-based player character triggers collisions with the ground at higher and higher speeds, compared to KinematicBody2D-based characters.

The Area2D variant breaks down as soon as the game loop tick-based updates skip floor tiles; the physics-based approach calculates in-between collisions for much, much longer.

But at much higher speeds, even there you will see this begins to break down.

At speeds where the player moves from one edge of the screen to the next in a split-second, even the KinematicBody2D hit detection shows problems

I wonder if I would have to utilize ray-tracing in Godot to check for collisions along the ray in the direction of the movement. Or maybe there’s a knob I can turn to increase the hit detection accuracy at higher speeds. (It does not help to chop the movement into e.g. 100 steps and call move_and_collide 100 times on 1/100th of the vector. Tried that. I guess the detection happens after the method call.)

If I would have to write this stuff in my own engine, it’d look like this:

// Let's ignore Y-axis and height for the example
struct Space {
    let x: Int
    let width: Int
}

var playerSpace = Space(x: 0, width: 10)

func moveRight(by speed: Int) {
    let old = playerSpace
    let new = Space(
        x: playerSpace.x + speed,
        width: playerSpace.width)
    let spaceBetween = Space(
        // Start to the right of the old space:
        x: old.x + old.width,
        // End just before the new space:
        width: new.x - old.x - old.w)
    playerSpace = new

    consumeCoins(in: playerSpace)
    consumeCoins(in: spaceBetween)
}

For collision detection that actually puts a stop to player movement, you cannot just set the new position via old.x + speed, but you have to intercept the movement and utilize something like walls(in: spaceBetween).first.x (or .last.x when you move left).

I’ll have to experiment with physics bodies in Godot some more and see if collision detection is 100% accurate even at ridiculous speeds when both objects are physics-based, and not just the player, moving on top of Area2D objects.

Play the demo
Check out the code on GitHub

How to Decode Human-Readable JSON Strings to Integer-Based Swift.OptionSet

I want to decode JSON that’s human readable but still represents a Swift.OptionSet. Traditionally, OptionSets are implemented with an integer-based rawValue, because that gives you the set algebra for free.

Here’s my type:

struct Selection: OptionSet {
    typealias RawValue = Int
    let rawValue: Int

    init(rawValue: Int) {
        self.rawValue = rawValue
    }

    static let selected = Selection(rawValue: 1 << 0)
    static let all = Selection(rawValue: 1 << 1)
}

Here, all represents the whole text of a document, for example, and selected stands for the current selected text, if any.

The JSON to configure the required input should be:

{
"selection: [ "all" ]
}

To get Swift.Decodable for free, I would usually have to use the integer values in the JSON array. The JSON should be human-readable, though, so instead of writing 2, people should be able to write "all".

Here’s a very direct, very naive approach that works just fine:

extension Selection: Decodable {
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        switch try container.decode(String.self) {
        case "selected": 
            self = Selection.selected
        case "all": 
            self = Selection.all
        case let unrecognized: 
            let context = DecodingError.Context(
                codingPath: decoder.codingPath,
                debugDescription: "Selection not recognized: \(unrecognized)")
            throw DecodingError.valueNotFound(String.self, context)
        }
    }
}

The string-to-number-mapping has to be encoded somewhere. Here, it’s in the switch-case statement.

You can also provide a proper map data type instead:

extension Selection: Decodable {
    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        let optionName = try container.decode(String.self)
        guard let selection = Selection.mapping[optionName] else {
            let context = DecodingError.Context(
                codingPath: decoder.codingPath,
                debugDescription: "Selection not recognized: \(optionName)")
            throw DecodingError.valueNotFound(String.self, context)
        }
        self = selection
    }

    private static let mapping: [String : Selection] = [
        "selected" : .selected,
        "all" : .all
    ]
}

Which one to use?

It really does not matter. There’s no difference in functionality, it’s just style.

I prefer the mapping data type, because I don’t have to touch the init(from:) initializer anymore, and I find the data type declaration a bit easier on the eye. There’s no context at all – it’s just a dictionary, and that’s it.

The case let unrecognized was nice. I like pattern matching. But the guard clause is super simple, too. There’s no real ground to argue for one or the other, as is often the case in programming. So pick whichever you like best, and happy coding.

Patching console.log into Swift's JavaScriptCore JSContext

By default, you cannot print to the Xcode console from within a JavaScriptCore-evaluated script. print, echo, console.log – nothing of the like is available.

Caveman debugging is tremendously useful, though, so we all know that we want to print from the JavaScript we evaluat, right?

With my subscript extensions, you can patch this into your JSContext in a rather simple manner.

Note that the usual console.log("hello!") call is a method call (log) on the console object. Without my subscript extensions, you’d have to use the objectForKeyedSubscript getter on the JSContext first to get to the console object, and then use setObject(_:forKeyedSubscript:) on the JSValue to add a block that prints a String. With the extension, we can write this instead:

let logHandler: @convention(block) (String) -> Void = { string in
    print(string)
}
jsContext["console"]?["log"] = logHandler

We still have to add the @convention(block) annotation, though. Without it, the logHandler would be passed in as an NSObject reference – but these cannot be called like a regular function can, so that won’t help.

I think this subscript stuff is quite useful. Reduces the noise tremendously.

Please keep in mind that the actual console.log API documentation clearly states that you can pass more than mere strings to this method. It supports variadic arguments for formatted strings, and it supports printing objects. I leave this as an exercise for the reader, heh.

Add Subscripts to JavaScriptCore Types in Swift

The JavaScriptCore framework was apparently very convenient to use in Objective-C times: you could simply use subscripts to change objects inside the context, like this:

jsContext[@"objectName"][@"property"] = @"hello!";

In Swift, tutorials you find on the web stick to the longer version that underlies the subscript convention here: method calls to -objectForKeyedSubscript and -setObject:forKeyedSubscript:.

For example:

// Getter:
if let variableHelloWorld = jsContext.objectForKeyedSubscript("helloWorld") {
    print(variableHelloWorld.toString())
}

// Setter:
let luckyNumbersHandler: @convention(block) ([Int]) -> Void = { luckyNumbers in
    // ...
}
jsContext.setObject(
    unsafeBitCast(luckyNumbersHandler, to: AnyObject.self), 
    forKeyedSubscript: "handleLuckyNumbers" as (NSCopying & NSObjectProtocol)!)

Here are a couple of tips:

  • You can shorten "foo" as (NSCopying & NSObjectProtocol)! to "foo" as NSString.
  • You don’t need to use unsafeBitCast and can pass Swift blocks directly to a JavaScriptContext.
  • You can write custom Swift extensions for the subscripts.

Swift Subscripts for JSContext and JSValue

Here’s an extension to the two core types that support subscripting. The method signatures of both JSContext and JSValue are a bit different. One takes key: Any!, one takes key: (NSCopying & NSObjectProtocol)!, for example. That’s why we need to duplicate the code – a common protocol abstraction won’t work without producing more than 3x the code. (I tried.)

extension JSContext {
    subscript(_ key: NSString) -> JSValue? {
        get { return objectForKeyedSubscript(key) }
    }

    subscript(_ key: NSString) -> Any? {
        get { return objectForKeyedSubscript(key) }
        set { setObject(newValue, forKeyedSubscript: key) }
    }
}

extension JSValue {
    subscript(_ key: NSString) -> JSValue? {
        get { return objectForKeyedSubscript(key) }
    }

    subscript(_ key: NSString) -> Any? {
        get { return objectForKeyedSubscript(key) }
        set { setObject(newValue, forKeyedSubscript: key) }
    }
}

With that, statements become a lot simpler:

// Setter
jsContext["foo"] = 123

// Getter
print(jsContext["helloWorld"]?.toString())

h-now Aggregator Live Demo on Heroku

Last week, I proposed the h-now microformat and whipped up a crappy PHP demo app to show what it’s about.

Big thanks now go to Roman Veselý (@crazko) who put this up on Heroku. You can viewand use the aggregator live here: https://hnow.herokuapp.com/

If you want to see it with a couple of your favorite /now pages pre-populated, click this link instead.

Matthias Pfefferle already updated his Wordpress theme to support the microformat. It’s so simple, you can do it, too!

FSCheckoutSheet: In-App Purchase Sheet for Your FastSpring Store

Screenshot of the sheet displaying Helge’s macOS native Slack client that you should check out, too!

Helge Heß published an Open Source component to use the modern FastSpring web API so you can display a sheet to purchase a license of your app within your app.

It’s not yet a native in-app purchase UI or anything, but you can

  • display your product from your FastSpring store,
  • process orders in the sheet, since it’s just a WKWebView, and
  • automatically activate the app after the order is completed.

The last part is probably the most important to me. It’s what I like most about the

Check out FSCheckoutSheet on GitHub: https://github.com/ZeeZide/FSCheckoutSheet/

Structure and Interpretation of Classic Mechanics – A Physics Book with Code

Maybe nobody is suprised that the book “Structure and Interpretation of Classic Mechanics” by Sussman & Wisdom contains code that you can put in any old Scheme/Lisp environment to actually represent mechanical equations.

Like this expression:

q(t)=x(t),y(t),z(t)

Turned into this code:

(define q
  (up (literal-function x)
      (literal-function y)
      (literal-function z)))
(q t)
;; =>  (up (x t) (y t) (z t))

Imagine if it was interactive on the web!

It should not be a surprise because the book title is so similar to “The Wizard Book”, “Structure and Interpretation of Computer Programs”. Which is a very, very interesting read, both to get to know their didactics for hands-on “how to learn to program” course, and to see how you can actually express weird concepts in a functional language.

Both books are super fascinating, and both links here point to the MIT Press pages where you can read the books for free, online. That’s right: With copy & pasting of the code.


→ Blog Archive