Changelog für Sonntag:
- Bugfixes bei Portalen
- Multiplayer-Modus eingeführt: Man sieht jetzt, wo die anderen Spieler herumlaufen
Der Multiplayer-Modus hat ein paar Schmankerl, von denen ich gerne erzählen möchte:
Das ganze basiert auf Websockets. Da die Spiele-Engine selbst auf PHP basierte, musste ich dazu zu einer anderen Technologie greifen: MemCP
MemCP ist eine MySQL-protokollkompatible in-Memory-Datenbank mit einem eigenen Modulsystem und genau das habe ich benutzt, um direkt in der Datenbank einen Websocket-Server zu öffnen und ein Publish-Subscribe-Pattern zu implementieren. Der Code ist ganz simpel:
Code: Alles auswählen
(eval (parse_sql "hardlife" "CREATE TABLE IF NOT EXISTS avatar(ID int, x double, y double, z double, r double, location int, UNIQUE KEY PRIMARY(ID))"))
(eval (parse_sql "hardlife" "CREATE TABLE IF NOT EXISTS avatarListen(ID int, container int, UNIQUE KEY PRIMARY(ID, container))"))
(eval (parse_sql "hardlife" "CREATE TABLE IF NOT EXISTS avatarDirty(ID int, other int, UNIQUE KEY PRIMARY(ID, other))"))
(set update_location_prepared (parse_sql "hardlife" "INSERT INTO avatar(ID, x, y, z, r, location) VALUES (@avatar, @x, @y, @z, @r, @l) ON DUPLICATE KEY UPDATE x = @x, y = @y, z = @z, r = @r, location = @l"))
(set update_dirtylist_prepared (parse_sql "hardlife" "INSERT IGNORE INTO avatarDirty(ID, other) SELECT ID, @avatar FROM avatarListen WHERE ID != @avatar AND container = @l"))
(set clear_listen_prepared (parse_sql "hardlife" "DELETE FROM avatarListen WHERE ID = @avatar"))
(set insert_listen_prepared (parse_sql "hardlife" "INSERT IGNORE INTO avatarListen(ID, container) VALUES (@avatar, @l2)"))
(set get_listen_prepared (parse_sql "hardlife" "SELECT avatar.ID, avatar.x, avatar.y, avatar.z, avatar.r, avatar.location AS l FROM avatarDirty, avatar WHERE avatar.ID = avatarDirty.other AND avatarDirty.ID = @avatar"))
(set clear_dirty_prepared (parse_sql "hardlife" "DELETE FROM avatarDirty WHERE ID = @avatar"))
Es werden also alle Avatar-Positionen in avatar gespeichert, sowie eine Liste aller Räume, die man auf dem Bildschirm sieht in avatarListen. Reportet jetzt ein Spieler seine Position, bekommt er im Gegenzug die veränderten Positionen aller anderen Spieler, die zwischendurch in avatarDirty gesammelt wurden.
Die SQL-Queries werden als prepared Statements vorbereitet und somit fertig auscompilt. Beim entsprechenden Event müssen sie nur noch aufgerufen werden. Kein Address-Space-Wechsel wie sonst bei TCP/Socket-basierten Datenbankanbindungen.
Long Story Short: Wenn ihr euch auf
hardlife.io einloggt, könnt ihr eventuell ein paar andere Spieler ebenfalls beobachten.