HowTo rC3 world maps
===

[english version](maps.en.md)

Auch dieses Jahr wird es zur rC3 wieder eine Art 2D-Adventure, die rC3.world,
geben. Dieses Tutorial soll erklären, wie Karten und Inhalte zur rC3.world
beigesteuert werden können. Falls danach noch Fragen offen sind, meldet euch
gerne per [Email](mailto:world@rc3.world) und wir versuchen das Tutorial zu
ergänzen.

## Metainformationen

### Disclaimer
Dieses Tutorial ist ein work in progress und wird immer mal wieder erweitert,
es lohnt sich daher mehrfach hier vorbeizuschauen.

### Known Bugs
Folgende Bugs sind aktuell bekannt, wir versuchen bereits, Lösungen dafür zu
finden:

* Ausgänge können nicht auf dem rechten Rand der Karte liegen
* das gleiche Tileset (mit dem gleichen Namen) mehrfach einbetten führt zu
  Darstellungsfehlern in WorkAdventure



## Schnell-Überblick

### Limitierungen
Instanzen skalieren nicht unendlich: zwar kann die Infrastruktur an sich
inzwischen auch Räume mit deutlich mehr gleichzeitigen Nutzer:innen verkraften,
da aber Workadventure weiterhin versuchen wird, alle Avatare gleichzeitig
anzuzeigen überlastet ihr damit einfach nur Browser und Internetleitungen.
Unsere Erfahrung zeigt, dass das Limit irgendwo bei 200 Nutzer:innen liegt.
Bitte denkt beim Karten erstellen daran.

Die Map-Größe kann davon unabhängig relativ flexibel dimensioniert werden.
Karten im Bereich von 50x50 Tiles laufen ziemlich gut, Karten im Bereich von
500x500 gehen mit einer relevanten Ladezeit einher. Wir raten generell dazu,
nicht unnötig riesige Karten zu bauen, damit Besucher:innen darin nicht "verloren
gehen" und auch Chancen haben, einander zu finden.

Benutzt bitte keine Tilesets, deren Textur größer ist als 4096 auf 4096 Pixel;
sonst kann es je nach Endgerät zu Darstellungsfehlern kommen, falls derart große
Texturen [nicht von WebGL unterstütz werden.](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#understand_system_limits)

Ausgehenden Links wird (wie letztes Jahr auch) wieder ein Dereferrer ("du verlässt
jetzt das Gelände") vorgeschaltet.


### Scripte
Die "[scripting API extra](https://workadventu.re/map-building-extra/about.md)"
könnt ihr nach Belieben benutzen, wir werden alle dort enthaltenen Features
unterstützen. Selbst geschriebene Scripte sind aufgrund des dadurch für uns
enstehenden Review-Aufwands nur auf Anfrage möglich.

### Starter-Kit
Es wird auch dieses Jahr wieder ein Starter Kit geben, dass ihr einfach
herunterladen, als Vorlage benutzen, oder forken und in eure eigene Map
umbauen dürft. Dies ist – ebenso wie Tileset-Vorlagen — aktuell noch in
Arbeit und wird hier verlinkt sobald es fertig gestellt ist, gedultet
euch also noch ein wenig.


### Best Practices
Um den Besuch der Welt möglichst angenehm zu gestalten haben hat sich über
vergangene Veranstaltungen
[eine Liste an Best Practices für die Kartengestaltung](map-best-practices.md)
ergeben. Bitte lest sie euch aufmerksam durch und behaltet sie beim Gestalten
eurer neuen (oder Überarbeiten älterer) Maps im Hinterkopf und passt sie ggf.
daran an.

Bei einigen besonders offensichtlichen Verstößen (z.B. Ausgänge auf nicht
existierende Karten) macht euch außerdem der Maschinenraum darauf aufmerksam
oder schlägt Verbesserungen vor.


### Wie kommts später in die world?
Um Karten in der Welt einbringen zu können, müsst ihr ein
[Assembly anmelden](https://maschinenraum.rc3.world/).

Eure Karten legt ihr dann bitte in einem Git-Repo eurer Wahl ab und tragt im
Maschinenraum dessen URL ein. Unser Backend wird eure Karte dann regelmäßig von
dort herunterladen, mit einem rudimentären Linter auf einige Anforderungen und
generelle Sinnhaftigkeit prüfen, und daraufhin an rc3.world ausspielen.

Bitte beachtet, dass eure Karte auch abgelehnt werden kann, falls sie Fehler
enthält (z.B. Ausgänge auf Karten zeigen, die gar nicht existieren) oder sie
einfach im falschen Format ist. In diesem Fall wird euch das im Maschinenraum
angezeigt und entsprechend begründet — falls sich eure Karte also auch nach
mehrmaligem neuladen nicht verändert hat, schaut bitte einmal dort nach.

### Links zwischen einzelnen Karten

Innerhalb eures Repositories könnt ihr ganz normale, relative Links benutzen —
um von einer Karte `main.json` auf eine zweite Karte `garten/geheimbasis.json`
zu verlinken, tragt also einfach den enstprechenden Pfad ein (andersrum genauso:
von `garten/geheimbasis.json` zurück nach `main.json` geht es per `../main.json`).

Dasselbe gilt natürlich auch für Links zu Tilesets usw.

Bitte benutzt *keine* absoluten Pfade (d.h. Pfade, die mit einem `/` anfangen),
da diese auf rc3.world dann außerhalb eures Assemblies liegen würden.

### Links zu Orten außerhalb des eigenen Assemblies

**Achtung:** Funktioniert anders als letztes Jahr!

Um von zu anderen Assemblies oder allgemein anderen Orten (z.B. zur Lobby oder
Lounge) zu linken gibt es ein spezielles Link-Schema:

`world://<assembly>/<map>.json`

Dabei steht `assembly` für den "Technischen Namen" (bzw. Slug) des Ziel-Assemblies,
so wie ihr ihn im Maschinenraum für euer eigenes Assembly festlegen könnt. Der
Pfad danach bezieht sich dann auf den Ort der Map innerhalb des Git-Repositories
dieses Assemblies.

Um zurück in die Lounge zu kommen, benutzt als slug einfach `lounge`.

Da die Gültigkeit dieser Links nicht von eurem eigenen Repository, sondern auch vom
Rest der Veranstaltung abhängt (und sich auch mit der Zeit ändern kann), können
ungültige Links hier aktuell nicht statisch beim Hochladen eurer Karten abgefangen
werden — achtet also bitte selbst darauf, dass eure Links nicht ins Nichts führen.


### Einstiegspunkte und Lobby
Wir gestalten zentrale Einstiegskarten, über die man dann zu euren Assembly-Karten
gelangt.

Eure Assembly-Karte sollte natürlich auch einen Ausgang zurück zur Lobby
enthalten. Als einheitlichen, wiedererkennbaren Ausgang zur Lobby-Karte empfehlen
wir euch dafür dieses Tile zu verwenden:

![](https://tiles.rc3.world/rc3-2021/worldExit.png)




# Kartengestatung

## Tiles
Grundlegend bestehen die Karten aus sogenannten Tiles oder Sprites (auch wenn es
Unterschiede zwischen den Begriffen gibt werden sie hier im Folgenden synonym
verwendet). Bitte benutzt ausschließlich Tiles der Größe 32x32 Pixel.

Tiles können Transparenz beinhalten und liegen im png-Format vor.

### Tiles finden

* Wir stellen euch im [Shared Tiles Repo](https://tiles.rc3.world/) viele extra
für das Event erstellte Tiles zur Verfügung. Ihr könnt das Repository auch
als Submodule in euer Karten-Repo einbinden: `https://git.cccv.de/rc3/world-tiles.git`.
* Tiles gibt es massig im Internet, häufig zu Tilesets (mehrere Tiles zu einem
  Thema) zusammengefasst.
* Seiten auf denen ihr schöne Tiles finden könnt sind zum Beispiel:
    * [itch.io](https://itch.io/)
    * [opengameart.org](https://opengameart.org/)
    * [deviantart.com](https://www.deviantart.com/)
* Achtet auf die Größe der Tiles!
* Achtet auf die Lizenz der Tilesets
    * wir werden nicht aktiv prüfen, unter welcher Lizenz eure Tiles stehen,
      allerdings nach dem Prinzip "takedown on notice" auf Verstöße reagieren.
    * tragt die Lizenz eurer Tilesets in die custom property `tilesetCopyright` ein



### Tiles gestalten / "pixeln"
Tiles können auch selbst gestaltet bzw. vorhandene verändert werden, was häufig
auch "pixeln" genannt wird. Hierzu empfiehlt sich der Editor
[krita](https://krita.org/), es geht aber prinzipiell auch mit anderen.

* Achtet auch hierbei darauf, dass die Tiles 32x32 Pixel groß sind. Ihr könnt
  euch unter view -> show grid ein Raster einblenden und unter settings ->
  dockers -> grid and guides den Einstellungs-Docker einblenden, in dem ihr die
  Grid-Größe festlegen könnt.
* Falls ihr Übergänge von Materialien gestalten müsst, nutzt Transparenz und
  baut Übergänge von einem Material zu Transparenz, das ist vielseitiger nutzbar
  und erspart euch, zu jedem anderen Material einen Übergang gestalten zu müssen.
* Auf media.ccc.de könnt ihr euch den [Pixel-Art Workshop von blinry](https://media.ccc.de/v/34C3-jugend-hackt-1016-pixel_art_workshop)
  ansehen


## Maps
Karten können mittels des Editors [Tiled](https://www.mapeditor.org) erstellt
werden. Ähnlich wie in diversen Zeichenprogrammen können Karten aus mehreren
Layern bestehen, die beim Rendern übereinander gelegt werden. Layer können
transparent gestaltet werden.

### Neue Karte in Tiled anlegen
Achtet beim Erstellen einer neuen Karte auf folgende Einstellungen:

* die Karte muss orthogonal sein, und Tilesize muss 32x32 Pixel sein
* Während des Erstellens kann es sinnvoll sein, eine unendliche Karte zu
  verwenden, anstatt sich vorab auf eine Größe festzulegen. Dies muss beim
  finalen Speichern der Karte wieder aber wieder auf eine feste Größe geändert
  werden!

### Karte gestalten - Layer
Eine Karte kann aus beliebig vielen übereinander gelegten Tile Layern bestehen.
Eure Karte braucht dabei mindestens einen mit dem Namen `start`. Standardmäßig
werden neue Besucher\*innen dann zufällig auf einer der Tiles dieses Layers
starten (am besten schiebt ihr diesen Layer im Stapel ganz nach unten, damit
diese Tiles einfach von den anderen überdeckt werden). Außerdem braucht ihr ein
Layer namens `floorLayer`, dessen Typ `objectgroup` sein muss und der definiert,
auf welchem Layer sich die Avatare bewegen bzw. was vor- oder hinter ihnen
angezeigt werden soll.

![](img/layer.png)

Für ein leichteres Gestalten hebt euch den aktuellen Layer hervor:

![](img/settings_show_animations.png)

### Wände / Kollisionen
Um Tiles als undurchgängig zu markieren, müsst ihr diese im Tileeditor öffnen
und die custom property `collides` (Boolean `true`) für das jeweilige Tile
(nicht dem enthaltendem Layer!) setzen. Vergesst nicht, euer Tileset anschließend
zu speichern! Tiled bietet zwar auch die Möglichkeit "collision shapes" für
einzelne Tiles festzulegen, diese werden von workadventure allerdings nicht
unterstützt und einfach ignoriert.

![](img/edit_tileset.png)

![](img/cp_collides.png)

### Tiles einbinden
Tilesets müssen in Tiled in die Map eingebunden werden, ein Verweis auf externe
Tilesets im TSX Format ist nicht möglich. (Das heißt nicht, dass die Bilddateien
mit eingebunden sind. Die PNG-Dateien müssen ebenfalls auf den Server geladen
werden bzw. in eurem Repository vorhanden sein.)

Achtet bitte auf die Lizenzen der verwendeten Tiles und tragt deren Copyright in
die custom property `tilesetCopyright` ein.

### Zusatzfunktionen für Layer

#### Weitere Eingänge
Neben dem `start` Layer könnt ihr weitere Einstiegspunkte zu eurer Karte
definieren, i.e. "Eingänge", die Besucher\*innen direkt an bestimmte Stellen
springen lassen. Diese Layer funktionieren sehr ähnlich: setzt einfach beliebige
Tiles an die Stelle, wo die Spielfigur spawnen soll. Um sie als Einstiegspunkt
zu markieren, setzt in Tiled die Custom Property `startLayer` (Typ Boolean) auf
`true`. Der Name dieses Layers ist auch die "Sprungadresse", die ihr zum Betreten
über diesen Layer braucht. Wenn eure Karte also z.B. `foo.json` heißt und der
Layer, auf den ihr springen wollt, `bar`, dann wäre die Adresse dafür `foo.json#bar`.

![](img/cp_startlayer.png)

#### Ausgänge
Exits zu anderen Maps funktionieren ähnlich: legt einen neuen Layer an, packt
an die Stellen, an denen ihr Ausgänge haben wollt, beliebige Tiles, und gebt
dem Layer die Custom Property `exitUrl` (vom Typ String). Diese setzt ihr
auf die Url der Karte, zu der dieser Ausgang führen soll, also z.B. `foo.json#bar`,
um in der Karte `foo.json` auf einen Startpunkt `bar` zu springen (falls ihr
das `#bar` weglasst, führt der Ausgang stattdessen zum `start`-Layer von
`foo.json`).

![](img/cp_exiturl.png)

Zu Ausgängen in die Lobby, Lounge, oder zu anderen Assemblies, werft einen Blick
auf die Kurzübersicht weiter oben.


### Webseite einbinden
Ihr könnt Webseiten einbinden, die sich beim Betreten von bestimmten Tiles öffnen.
Analog zu Start und Exit Layern legt ihr ein Layer dafür an, setzt Tiles an die
entsprechenden Stellen und gebt dem Layer die custom property `openWebsite`
(Typ String). Verwendet https!

Allgemein wird empfohlen, zusätzlich noch die Property `openWebsiteTrigger` auf
`onaction` zu setzen, damit die Website erst nach explizitem Wunsch (einem
Druck auf die Leertaste) aufgeht. Das macht den Besuch der World für langsamere
Endgeräte angenehmer.
Außerdem könnt ihr mit der Property `openWebsiteTriggerMessage` noch
eine kurze eigene Nachricht einstellen, die Besucher\*innen angezeigt wird, wenn
sie auf den Bereich der Website laufen (dies überschreibt die Standardnachricht
"Press SPACE or touch here to open web site").

![](img/cp_openwebsite.png)

Beachtet außerdem, dass Webseiten außerhalb der rC3 auf der rc3.world automatisch
einen dereferrer vorgehängt bekommen, der Besucher\*innen darauf hinweißt, dass
sie jetzt "das Gelände verlassen".

### Jitsi einbinden
Auf die selbe Art könnt ihr auch Jitsi Räume in eure Karte einbinden. Setzt dazu
einfach die custom property `jitsiRoom` (Type String) und gebt ihr als Wert den
Namen den euer Jitsi Raum haben soll.

![](img/cp_jitsiroom.png)

Um Kollisionen zwischen verschiedenen Assemblies zu verhindern (damit z.B.
alle ihr eigenes "Hackcenter" definieren können) sind die Namen der Jitsi-Räume
standardmäßig lokal für euer Assembly. Falls ihr einen Raum mit einem anderen
Assembly teilen wollt, hängt bitte vorne an den Namen `shared-` an.

Allgemein wird empfohlen, zusätzlich noch die Property `jitsiTrigger` auf
`onaction` zu setzen, damit der Jitsi-Raum erst nach explizitem Wunsch (einem
Druck auf die Leertaste) aufgeht. Das macht den Besuch der World für langsamere
Laptops angenehmer und verhindert, dass sich versehentlich wer in eure laufende
Session verirrt. Außerdem könnt ihr mit der Property `jitsiTriggerMessage` noch
eine kurze eigene Nachricht einstellen, die Besucher\*innen angezeigt wird, wenn
sie auf den Bereich des Jitsis laufen (dies überschreibt die Standardnachricht
"Press SPACE or touch here to enter Jitsi Meet room").

### Big Blue Button einbinden
Dies funktioniert im wesentlichen genauso wie für Jitsi: setzt `bbbRoom` auf den
Namen eures Raums, und `bbbTrigger` bzw. `bbbTriggerMessage`, um den Raum nicht
unverhofft aufploppen zu lassen.

### Stille Bereiche
Solltet ihr in gewissen Bereichen keine Audio/Video Kommunikation zwischen den
Teilnehmern wollen, so könnt ihr hierfür einen eigenen Layer anlegen und diesem
die custom property `silent` (bool true) geben. Auf allen Tiles dieses Layers
sind danach keine Gespräche mehr üblich. Besonders sinnvoll ist das z.B. in engen
Gängen, in denen man sich nicht ohne weiteres ausweichen kann.

![](img/cp_silent.png)

### Badgevergabe
Ihr könnt Badges an User vergeben. Legt dazu einen Layer vom Typ `objectgroup`
(wichtig!) an, und platziert dann keine Tiles, sondern Punkte und / oder Rechtecke
auf diesem Layer. Setzt dann noch die Custom Property `getBadge` (Typ String) auf
das Token eurer Badge (an dieses kommt ihr im Maschinenraum, wo ihr auch neue
Badges anlegen könnt). Es funktioniert jedoch nur ein **Map** Redeem Token.

Wenn jetzt Besucher\*innen über die entsprechenden Stellen der Map laufen, werden
sie eure Badge erhalten.

![](img/cp_getBadge.png)

### Animationen
Tiles können zu Animationen (Loops) zusammengeführt werden, um z.B. fließendes
Wasser oder blinkende Lichter darzustellen. Dazu müssen alle "Frames" einer
Animation jeweils ein eigenes 32x32 Tile sein. Bearbeitet dazu in Tiled das
Tileset, wählt das zu animierende Tile (oder ein beliebiges leeres Tile) aus
und klickt auf den Animation Editor:

![](img/animation_editor.png)

Dann können alle Tiles, die Bestandteil der Animation sein sollen, per Drag and
Drop in die "playlist" gezogen werden und die Anzeigedauer in Millisekunden
eingestellt werden:

![](img/animation.png)

Im Map-Editor sollten die Animationsloops auch schon dargestellt werden, sobald
die Option im "view" Menü gesetzt ist:

![](img/settings_show_animations.png)

Hinweis: Die in Workadventure verwendete Engine macht Tile-Updates nur alle 100ms, also werden Animationen
mit Framedurations unter 100ms vermutlich nicht gut aussehen oder gar nicht
funktionieren.

Größere Animationen über mehrere Tiles müssen in Tiled Editor Tile für Tile animiert
werden, funktionieren aber relativ problemlos. (Gelegentlich laufen einzelne
Tiles nicht synchron zum Rest, wir wissen doch auch nicht..)

### Sound
Layer mit der Property `playAudio` (Typ String) spielen beim Betreten der
zugehörigen Tiles Sound ab. Unterstützt werden mp3-Dateien, die relativ zum Pfad
der Karte eingebunden werden können. Externe mp3-Dateien können nicht eingebunden
werden. Falls ihr Streams eimbinden wollt wendet euch bitte an
[world@rc3.world](mailto:world@rc3.world). Soll sich der Audioschnipsel wiederholen,
so setzt zusätzlich `audioLoop` (Typ Boolean) auf `true`.
Wenn die Audiodatei leiser wiedergegeben werden soll, kann das mit der Property
`audioVolume` eingestellt werden, die eine Fließkommazahl zwischen `0.0` (0%) und
`1.0` (100%) annehmen kann. User können auch client-seitig eine Maximallautstärke
einstellen - es wird dann immer der kleinere Wert verwendet.

![](img/cp_playaudio.png)

Bitte verwendet nur **GEMA-freie** Soundschnipsel! Falls ihr Streams einbindet,
müsst ihr außerdem eine Trackliste anlegen um der GEMA nachweisen zu können,
dass ihr nur freie Musik gespielt habt.

Tragt das Copyright für eure Musik bitte in der `mapCopyright` property auf der
Map direkt ein, da es (aktuell) keine spezielle Property pro `playAudio`-Layer
dafür gibt.

# Paketierung, Deployment und Infrastruktur

## Karte speichern / exportieren
Karten müssen als json gespeichert werden, Tilesets sollten vorher eingebunden
werden. Die relevanten Dateien sind anschließend eure Karten im json-Format und
die verwendeten Tilesets als png.

Unendliche Karten müsst ihr vor dem Speichern in endliche umwandeln, hierzu
einfach in den Properties der Karte den Haken bei "infinite" entfernen und
speichern.

![](img/map_properties.png)

## Lizenzen
Achtet bitte bei euren Tilesets auf deren Lizenzen bzw. Copyright. Diese
müsst (!) ihr via der `tilesetCopyright` Property direkt in eurem Map json für die
jeweiligen Tilesets setzen.

Ebenso müsst (!) ihr für eure gesamte Map Lizenz bzw. Copyright in der custom
Property `mapCopyright` (Typ String) — gesetzt auf der Map, nicht einem
einzelnem Layer – angeben.

## Verzeichnisstruktur
Achtet beim Ablegen eurer Karten bitte auf die Verzeichnisstruktur, folgende
Dinge solltet ihr konkret beachten:

* Eure Startkarte muss `main.json` heißen und im Hauptverzeichnis liegen.
* Andere Karten können in eigenen Ordnern oder auch im Hauptverzeichnis liegen.
* Achtet bei Verlinkungen der Karten in eurer Karte auf die korrekte relative URL
  (siehe auch den entsprechenden Abschnitt oben).
* Achtet auf die Pfade eurer Tilesets (zur Not direkt im json anpassen).

Hier ein Beispiel wie ein Verzeichnis mit Karten exemplarisch aussehen könnte:

```
.
├── bla
│   └── keks.json
├── blubb.json
├── foo
│   ├── bar.json
│   └── tileset2.png
├── main.json
└── tileset.png
```


## Testen
Eine Testinstanz, auf der ihr eure Maps direkt testen könnt und die sich (soweit
möglich und sinnvoll) wie die "echte" Instanz für das Event verhält, ist aktuell
noch in Arbeit und kommt in Kürze.

## Eigene Instanzen
Wir werden sämtliche Instanzen für die rC3.world betreiben, versucht bitte nicht,
eigene Instanzen dafür aufzusetzen. Sprünge zu Instanzen außerhalb der rC3.world
werden nicht möglich sein.

<!--
## Infrastruktur
Die Infrastruktur der rC3.world wird von <a href="https://www.hetzner.com/de/cloud"><img src="img/hetzner-logo.svg" alt="hetzner online" width="100px" /></a> gesponsert.
-->