About Me

Bow Man Android Wear (April 2015)

Christoph Bühler, September 2020

I took it as a challenge to think of a small game that would be perfectly suited for playing on a smart watch. The biggest restriction would be the new form factor of a completely round screen and the limited performance of those first-gen devices. Most games would be visually too complex for a fun experience.

I ended up creating Bow Man Android Wear (a clone of the famous flash game) in one or two days just with the use of the native Java Canvas. It just felt like the perfect game for Android Wear. Unfortunately the game is not available anymore.

Game Mechanics

The player chooses a difficulty (easy or hard) and then starts the game against a computer. Both the player and the computer play as an archer. The archers stand with a random distance from each other.

By dragging from the top right corner of the device to the bottom left, the player can control both the angle and the force with which to shoot in the direction of the enemy. That is the only thing a player can do. After shooting, the camera animates from where the arrow hit the ground to the enemy and then it’s his turn.

When hit, an archer starts bleeding. Depending on where he has been hit, the damage dealt is worse. When the player or the enemy is dead, the game is over.

Feedback

I uploaded the game to the Play Store, expecting maybe a handful of downloads. It became my hobby for the upcoming weeks to check the downloads and the user feedback and I was happy about each one of them.

28,02K downloads and a rating of 3.8

I was surprised of getting thousands of downloads and plenty of nice reviews! The app was even featured as part of some small articles and YouTube videos.

Awesome! Pretty cool little game for a watch, really simple and works perfectly. On my previous review the Dev replied right away and fixed the only small issue I encountered, that’s awesome, thanks! I just hope you can add some variations to it. I’ve spent more time than I should on this so it’s getting easy and a little bit predictable. Maybe a hardcore difficulty with almost no fails from the computer, multiple enemies or something like unlockable armour, just an idea because the game is amazing as is.

A Google User

My First Neural Network (Aug 2015)

Christoph Bühler, September 2020

In an effort of archiving old projects I stumbled upon my first Neural Network in JavaScript. It’s a simple backpropagation network that can solve basic tasks like XOR.

Network Structure

This section is for creating the structure of the network. Layers are separated by spaces and the numbers define the amount of neurons on a given layer.

Training Data

Data for training the network can either be provided manually by entering every value (default is XOR) or by providing a function input.

Training Setup

This is where the network can be trained!

..seems like I wasn’t very patient back in 2015, setting the default maximum training duration of a NN to 100s 😉

Testing

After training a network, it can be tested in this section.

Bonus: Graph

If the network structure has exactly one input and one output, a graph appears, visualizing the training progress.

Creating a UI for Visual Reactive Programming

Christoph Bühler, September 2020

Flow-based programming (FBP) as a visual programming language is arguably one of the most understandable tools for communicating data flow of synchronous processes, addressing

How are processes wired together?

This article aims to lay out the challenges of leveraging this concept by going full reactive and answering the question of

When are processes executed?

A Synchronous Process with FBP

The following graph of a simple calculation can be understood by most and does not require proficiency in any programming language.

Flow-based programming

An implementation of this graph using pure functions in JavaScript:

const add = (a, b) => a + b;
const multiply = (a, b) => a * b;
const result = multiply(add(4, 7), 2); // 22

Given this example, the benefits of FBP become clear:

  • There are fewer ways of implementing a solution
  • Bugs are unlikely
  • Increased productivity
  • Better readability

Introducing Asynchronicity

Icon made by Freepik from www.flaticon.com

Let us try to visualize a simple game using FBP:

The direction of a spaceship is controlled by user input (left or right). The spaceship should continuously move in that direction until the direction is changed.

Asynchronicity in FBP

At this point it is unclear as to how this graph should be interpreted. When is Update Position called? On every tick or just when the direction changes? How can we describe the behavior we are trying to achieve visually?

In RxJS terminology we would use the merge operator for changing the direction and withLatestFrom for updating the position. One possible way of implementing our game with RxJS:

const pressLeft = controllerInput.pipe(ofType('left'));
const pressRight = controllerInput.pipe(ofType('right'));
const keyPress = merge(pressLeft, pressRight);
const tick = interval(1000 / 20);
const speed = .01;
const position = tick.pipe(
  withLatestFrom(keyPress),
  map(([, key]) => key === 'left' ? -1 : 1),
  map(dir => dir * speed),
  scan((posX, updateX) => posX + updateX, 0),
);

Proposal for a UI for Reactive Programming

When is B executed?

Input State

Examples

Managing Shared State in Flutter

Christoph Bühler, Januar 2020

When it comes to scalability and speed of development of a major code base, the communication between an ever growing number of components should be seamless. It felt like most of the existing Dart solutions for utilizing shared state were either too hard to maintain or did not satisfy my needs (coming from an NgRx background). So I decided to implement my own, lightweight solution.

Core Requirements

  • Change shared state without a lot of boilerplate.
  • React to state changes by utilizing Streams.
  • Everything is immutable.
  • Be type safe all the way (turned out to be the hardest challenge).

Dispatcher

The dispatcher contains the state and provides methods for updating state and sending and listening to actions for cross component communication.

abstract class AppAction {
  @override
  String toString() {
    return '[${this.runtimeType}]';
  }
}

class Dispatcher {
  Stream<Map<String, dynamic>> get state => _state.stream;
  final _state = BehaviorSubject<Map<String, dynamic>>.seeded({});
  final _messages = PublishSubject<AppAction>();

  Dispatcher();

  Observable<T> on<T extends AppAction>() {
    return _messages.where((m) => m is T).cast<T>();
  }

  void send(AppAction action) {
    _messages.add(action);
  }

  void updateState<T>(String property, T fn(T all)) {
    var state = _state.value;
    _state.add({...state, property: fn(state[property])});
  }
}

Entities

Entities are properties within the state that keep track of one entry (SingleEntity) or a collection (MultiEntity). Encapsulated entities are discouraged by design, as the state tree should be as flat as possible.

@immutable
abstract class EntityData {
  Map<String, dynamic> toJson();
  EntityData.fromJson(Map<String, dynamic> json);
  EntityData copy(Map<String, dynamic> additional);
  EntityData();
}

class SingleEntity<T> extends Stream {
  final Dispatcher _dispatcher;
  final String property;

  SingleEntity(
    this._dispatcher, {
    @required this.property,
    T initialValue,
  }) {
    if (initialValue != null) {
      update((_) => initialValue);
    }
  }

  void update(T fn(T prev)) {
    _dispatcher.updateState<T>(property, fn);
  }

  T _select(dynamic state) => state[property];

  @override
  StreamSubscription<T> listen(void onData(T event),
      {Function onError, void onDone(), bool cancelOnError}) {
    return _dispatcher.state.map(this._select).listen(onData,
        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
  }
}

class MultiEntity<T extends EntityData, IdentifierT> extends Stream {
  final Dispatcher _dispatcher;
  final String property;
  IdentifierT Function(T) identify;

  MultiEntity(
    this._dispatcher, {
    @required this.property,
    @required this.identify,
    List<T> initialValue,
  }) {
    addAll(initialValue ?? []);
  }

  void addOne(T value) {
    _dispatcher.updateState<List<T>>(property, (all) => [...?all, value]);
  }

  void addAll(List<T> values) {
    _dispatcher.updateState<List<T>>(property, (_) => values);
  }

  void removeOne(IdentifierT identifier) {
    _dispatcher.updateState<List<T>>(property,
        (all) => (all ?? []).where((entry) => identify(entry) != identifier));
  }

  void updateOne(T value) {
    IdentifierT identifier = identify(value);
    _dispatcher.updateState<List<T>>(
      property,
      (List<T> all) => (all ?? [])
          .map((entry) => identify(entry) == identifier ? value : entry)
          .toList(),
    );
  }

  Stream<T> selectOne(IdentifierT identifier) {
    return _dispatcher.state.map(_select).map((all) => (all ?? [])
        .firstWhere((entry) => identify(entry) == identifier, orElse: null));
  }

  List<T> _select(dynamic state) => state[property];

  @override
  StreamSubscription<List<T>> listen(void onData(List<T> event),
      {Function onError, void onDone(), bool cancelOnError}) {
    return _dispatcher.state.map(this._select).listen(onData,
        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
  }
}

Entity Data Types

Entities can either hold native data types or objects. Such objects have to implement fromJson, toJson and the copy method as shown in the following example. This might seem like a bit of an overhead, but because Reflection cannot be used with Flutter, we have to provide these methods to ensure type safety.

class Player extends EntityData {
  final int id;
  final String name;

  Player.fromJson(Map<String, dynamic> json)
    : id = json['id'],
      name = json['name'];

  @override
  Map<String, dynamic> toJson() => {
    'id': id,
    'name': name,
  };

  @override
  Player copy(Map<String, dynamic> additional) => Player.fromJson({
    ...toJson(),
    ...additional,
  });
}

Creating a Dispatcher and the Store

I recommend creating a store class that holds the entities. In this example, the `score` holds one value only while there can be multiple players.

final dp = Dispatcher();

abstract class Store {
  static final score = SingleEntity<int>(dp,
    initialValue: 0,
    property: 'score',
  );
  static final players = MultiEntity<Player, int>(dp,
    initialValue: [],
    property: 'players',
    identify: (player) => player.id,
  );
}

Working with this architecture

class GameOverAction extends AppAction {
  final int score;
  GameOverAction(this.score);
}

/// visualize the stream `Store.score`

/// update the score when the game is over
dp.on<GameOverAction>()
  .listen((action) => Store.score.update(
    (prevScore) => action.score)
  );

/// game over!
dp.send(GameOverAction(9000));