Просмотр исходного кода

Merge branch 'basics' of jan/smog into master

Jan 1 месяц назад
Родитель
Сommit
a85271ea17
34 измененных файлов с 2688 добавлено и 2 удалено
  1. 35 2
      README.md
  2. 8 0
      assets/assets.txt
  3. 198 0
      assets/ui/font-list.fnt
  4. 198 0
      assets/ui/font-subtitle.fnt
  5. 198 0
      assets/ui/font-window.fnt
  6. 198 0
      assets/ui/font.fnt
  7. 380 0
      assets/ui/uiskin.atlas
  8. 68 0
      build.gradle
  9. 20 0
      core/build.gradle
  10. 15 0
      core/src/main/java/me/lethunderhawk/Main.java
  11. 14 0
      core/src/main/java/me/lethunderhawk/entity/Player.java
  12. 75 0
      core/src/main/java/me/lethunderhawk/network/GameClient.java
  13. 29 0
      core/src/main/java/me/lethunderhawk/network/NetworkRegister.java
  14. 32 0
      core/src/main/java/me/lethunderhawk/network/Packets.java
  15. 105 0
      core/src/main/java/me/lethunderhawk/screen/GameScreen.java
  16. 117 0
      core/src/main/java/me/lethunderhawk/screen/MenuScreen.java
  17. 23 0
      gradle.properties
  18. 248 0
      gradlew
  19. 82 0
      gradlew.bat
  20. 209 0
      lwjgl3/build.gradle
  21. BIN
      lwjgl3/icons/logo.icns
  22. BIN
      lwjgl3/icons/logo.ico
  23. BIN
      lwjgl3/icons/logo.png
  24. 54 0
      lwjgl3/nativeimage.gradle
  25. BIN
      lwjgl3/src/main/resources/libgdx128.png
  26. BIN
      lwjgl3/src/main/resources/libgdx16.png
  27. BIN
      lwjgl3/src/main/resources/libgdx32.png
  28. BIN
      lwjgl3/src/main/resources/libgdx64.png
  29. 48 0
      lwjgl3/src/src/main/java/me/lethunderhawk/lwjgl3/Lwjgl3Launcher.java
  30. 227 0
      lwjgl3/src/src/main/java/me/lethunderhawk/lwjgl3/StartupHelper.java
  31. 44 0
      server/build.gradle
  32. 42 0
      server/src/main/java/me/lethunderhawk/server/GameServer.java
  33. 16 0
      server/src/main/java/me/lethunderhawk/server/ServerLauncher.java
  34. 5 0
      shared/build.gradle

+ 35 - 2
README.md

@@ -1,3 +1,36 @@
-# smog
+# Smog
 
-A multiplayer game made for testing my own capabilities
+A [libGDX](https://libgdx.com/) project generated with [gdx-liftoff](https://github.com/libgdx/gdx-liftoff).
+
+This project was generated with a template including simple application launchers and an `ApplicationListener` implementation that listens to user input.
+
+## Platforms
+
+- `core`: Main module with the application logic shared by all platforms.
+- `lwjgl3`: Primary desktop platform using LWJGL3; was called 'desktop' in older docs.
+- `server`: A separate application without access to the `core` module.
+- `shared`: A common module shared by `core` and `server` platforms.
+
+## Gradle
+
+This project uses [Gradle](https://gradle.org/) to manage dependencies.
+The Gradle wrapper was included, so you can run Gradle tasks using `gradlew.bat` or `./gradlew` commands.
+Useful Gradle tasks and flags:
+
+- `--continue`: when using this flag, errors will not stop the tasks from running.
+- `--daemon`: thanks to this flag, Gradle daemon will be used to run chosen tasks.
+- `--offline`: when using this flag, cached dependency archives will be used.
+- `--refresh-dependencies`: this flag forces validation of all dependencies. Useful for snapshot versions.
+- `build`: builds sources and archives of every project.
+- `cleanEclipse`: removes Eclipse project data.
+- `cleanIdea`: removes IntelliJ project data.
+- `clean`: removes `build` folders, which store compiled classes and built archives.
+- `eclipse`: generates Eclipse project data.
+- `idea`: generates IntelliJ project data.
+- `lwjgl3:jar`: builds application's runnable jar, which can be found at `lwjgl3/build/libs`.
+- `lwjgl3:run`: starts the application.
+- `server:run`: runs the server application.
+- `test`: runs unit tests (if any).
+
+Note that most tasks that are not specific to a single project can be run with `name:` prefix, where the `name` should be replaced with the ID of a specific project.
+For example, `core:clean` removes `build` folder only from the `core` project.

+ 8 - 0
assets/assets.txt

@@ -0,0 +1,8 @@
+.gitkeep
+ui/font-list.fnt
+ui/font-subtitle.fnt
+ui/font-window.fnt
+ui/font.fnt
+ui/uiskin.atlas
+ui/uiskin.json
+ui/uiskin.png

+ 198 - 0
assets/ui/font-list.fnt

@@ -0,0 +1,198 @@
+info face="font-list" size=12 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=2 padding=1,1,1,1 spacing=0,0
+common lineHeight=15 base=11 scaleW=505 scaleH=30 pages=1 packed=0 alphaChnl=0 redChnl=0 greenChnl=0 blueChnl=0
+page id=0 file="font-list.png"
+chars count=193
+char id=0     x=0    y=0    width=0    height=0    xoffset=-1   yoffset=11   xadvance=3    page=0    chnl=0
+char id=32    x=0    y=0    width=0    height=0    xoffset=-1   yoffset=-1   xadvance=3    page=0    chnl=0
+char id=33    x=391  y=14   width=2    height=7    xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=34    x=248  y=23   width=3    height=3    xoffset=-1   yoffset=4    xadvance=5    page=0    chnl=0
+char id=35    x=466  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=36    x=9    y=2    width=5    height=10   xoffset=-1   yoffset=3    xadvance=7    page=0    chnl=0
+char id=37    x=490  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=38    x=450  y=14   width=7    height=7    xoffset=-1   yoffset=4    xadvance=8    page=0    chnl=0
+char id=39    x=267  y=23   width=2    height=3    xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=40    x=126  y=2    width=3    height=9    xoffset=-1   yoffset=3    xadvance=4    page=0    chnl=0
+char id=41    x=131  y=2    width=2    height=9    xoffset=-1   yoffset=3    xadvance=4    page=0    chnl=0
+char id=42    x=46   y=23   width=4    height=5    xoffset=-1   yoffset=3    xadvance=5    page=0    chnl=0
+char id=43    x=73   y=23   width=6    height=5    xoffset=-1   yoffset=6    xadvance=7    page=0    chnl=0
+char id=44    x=263  y=23   width=2    height=3    xoffset=-1   yoffset=9    xadvance=3    page=0    chnl=0
+char id=45    x=306  y=23   width=4    height=1    xoffset=-1   yoffset=8    xadvance=5    page=0    chnl=0
+char id=46    x=296  y=23   width=2    height=1    xoffset=-1   yoffset=10   xadvance=3    page=0    chnl=0
+char id=47    x=354  y=2    width=4    height=8    xoffset=-1   yoffset=4    xadvance=5    page=0    chnl=0
+char id=48    x=383  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=49    x=317  y=14   width=3    height=7    xoffset=0    yoffset=4    xadvance=7    page=0    chnl=0
+char id=50    x=322  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=51    x=329  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=52    x=336  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=53    x=344  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=54    x=352  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=55    x=360  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=56    x=367  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=57    x=375  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=58    x=201  y=23   width=2    height=4    xoffset=-1   yoffset=7    xadvance=3    page=0    chnl=0
+char id=59    x=118  y=23   width=2    height=5    xoffset=-1   yoffset=7    xadvance=3    page=0    chnl=0
+char id=60    x=59   y=23   width=5    height=5    xoffset=-1   yoffset=6    xadvance=7    page=0    chnl=0
+char id=61    x=271  y=23   width=5    height=3    xoffset=-1   yoffset=7    xadvance=7    page=0    chnl=0
+char id=62    x=52   y=23   width=5    height=5    xoffset=-1   yoffset=6    xadvance=7    page=0    chnl=0
+char id=63    x=395  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=5    page=0    chnl=0
+char id=64    x=161  y=2    width=10   height=9    xoffset=-1   yoffset=4    xadvance=11   page=0    chnl=0
+char id=65    x=443  y=2    width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=66    x=494  y=2    width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=67    x=0    y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=68    x=8    y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=69    x=16   y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=70    x=24   y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=71    x=31   y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=72    x=54   y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=8    page=0    chnl=0
+char id=73    x=502  y=2    width=2    height=7    xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=74    x=332  y=2    width=3    height=8    xoffset=-1   yoffset=4    xadvance=4    page=0    chnl=0
+char id=75    x=69   y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=76    x=77   y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=77    x=84   y=14   width=8    height=7    xoffset=-1   yoffset=4    xadvance=9    page=0    chnl=0
+char id=78    x=94   y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=8    page=0    chnl=0
+char id=79    x=102  y=14   width=7    height=7    xoffset=-1   yoffset=4    xadvance=8    page=0    chnl=0
+char id=80    x=111  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=81    x=117  y=2    width=7    height=9    xoffset=-1   yoffset=4    xadvance=8    page=0    chnl=0
+char id=82    x=126  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=83    x=134  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=84    x=141  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=85    x=174  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=86    x=199  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=87    x=207  y=14   width=9    height=7    xoffset=-1   yoffset=4    xadvance=10   page=0    chnl=0
+char id=88    x=218  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=89    x=226  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=90    x=234  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=91    x=135  y=2    width=3    height=9    xoffset=-1   yoffset=3    xadvance=4    page=0    chnl=0
+char id=92    x=367  y=2    width=4    height=8    xoffset=-1   yoffset=4    xadvance=5    page=0    chnl=0
+char id=93    x=140  y=2    width=3    height=9    xoffset=-1   yoffset=3    xadvance=4    page=0    chnl=0
+char id=94    x=187  y=23   width=5    height=4    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=95    x=285  y=23   width=5    height=1    xoffset=0    yoffset=12   xadvance=7    page=0    chnl=0
+char id=96    x=258  y=23   width=3    height=3    xoffset=-1   yoffset=3    xadvance=3    page=0    chnl=0
+char id=97    x=88   y=23   width=5    height=5    xoffset=-1   yoffset=6    xadvance=6    page=0    chnl=0
+char id=98    x=241  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=99    x=95   y=23   width=4    height=5    xoffset=-1   yoffset=6    xadvance=5    page=0    chnl=0
+char id=100   x=248  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=101   x=101  y=23   width=5    height=5    xoffset=-1   yoffset=6    xadvance=6    page=0    chnl=0
+char id=102   x=255  y=14   width=4    height=7    xoffset=-1   yoffset=4    xadvance=4    page=0    chnl=0
+char id=103   x=261  y=14   width=5    height=7    xoffset=-1   yoffset=6    xadvance=6    page=0    chnl=0
+char id=104   x=268  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=105   x=275  y=14   width=2    height=7    xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=106   x=4    y=2    width=3    height=10   xoffset=-2   yoffset=4    xadvance=3    page=0    chnl=0
+char id=107   x=279  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=108   x=286  y=14   width=2    height=7    xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=109   x=108  y=23   width=8    height=5    xoffset=-1   yoffset=6    xadvance=9    page=0    chnl=0
+char id=110   x=122  y=23   width=5    height=5    xoffset=-1   yoffset=6    xadvance=6    page=0    chnl=0
+char id=111   x=129  y=23   width=5    height=5    xoffset=-1   yoffset=6    xadvance=6    page=0    chnl=0
+char id=112   x=290  y=14   width=5    height=7    xoffset=-1   yoffset=6    xadvance=6    page=0    chnl=0
+char id=113   x=297  y=14   width=5    height=7    xoffset=-1   yoffset=6    xadvance=6    page=0    chnl=0
+char id=114   x=15   y=23   width=4    height=6    xoffset=-1   yoffset=5    xadvance=4    page=0    chnl=0
+char id=115   x=136  y=23   width=5    height=5    xoffset=-1   yoffset=6    xadvance=6    page=0    chnl=0
+char id=116   x=304  y=14   width=4    height=7    xoffset=-1   yoffset=4    xadvance=4    page=0    chnl=0
+char id=117   x=143  y=23   width=5    height=5    xoffset=-1   yoffset=6    xadvance=6    page=0    chnl=0
+char id=118   x=150  y=23   width=5    height=5    xoffset=-1   yoffset=6    xadvance=6    page=0    chnl=0
+char id=119   x=157  y=23   width=8    height=5    xoffset=-1   yoffset=6    xadvance=9    page=0    chnl=0
+char id=120   x=167  y=23   width=5    height=5    xoffset=-1   yoffset=6    xadvance=5    page=0    chnl=0
+char id=121   x=310  y=14   width=5    height=7    xoffset=-1   yoffset=6    xadvance=6    page=0    chnl=0
+char id=122   x=174  y=23   width=5    height=5    xoffset=-1   yoffset=6    xadvance=6    page=0    chnl=0
+char id=123   x=145  y=2    width=4    height=9    xoffset=-1   yoffset=3    xadvance=5    page=0    chnl=0
+char id=124   x=157  y=2    width=2    height=9    xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=125   x=151  y=2    width=4    height=9    xoffset=-1   yoffset=3    xadvance=5    page=0    chnl=0
+char id=126   x=278  y=23   width=5    height=2    xoffset=-1   yoffset=7    xadvance=7    page=0    chnl=0
+char id=160   x=0    y=0    width=0    height=0    xoffset=-1   yoffset=11   xadvance=3    page=0    chnl=0
+char id=161   x=195  y=14   width=2    height=7    xoffset=-1   yoffset=6    xadvance=3    page=0    chnl=0
+char id=162   x=189  y=14   width=4    height=7    xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=163   x=182  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=164   x=8    y=23   width=5    height=6    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=165   x=166  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=166   x=180  y=2    width=2    height=9    xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=167   x=415  y=2    width=5    height=8    xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=168   x=312  y=23   width=4    height=1    xoffset=-2   yoffset=4    xadvance=3    page=0    chnl=0
+char id=169   x=0    y=23   width=6    height=6    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=170   x=181  y=23   width=4    height=4    xoffset=-1   yoffset=4    xadvance=5    page=0    chnl=0
+char id=171   x=66   y=23   width=5    height=5    xoffset=-1   yoffset=6    xadvance=6    page=0    chnl=0
+char id=172   x=241  y=23   width=5    height=3    xoffset=-1   yoffset=7    xadvance=7    page=0    chnl=0
+char id=174   x=498  y=14   width=6    height=6    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=175   x=300  y=23   width=4    height=1    xoffset=-2   yoffset=4    xadvance=3    page=0    chnl=0
+char id=176   x=235  y=23   width=4    height=3    xoffset=0    yoffset=4    xadvance=7    page=0    chnl=0
+char id=177   x=38   y=23   width=6    height=5    xoffset=-1   yoffset=6    xadvance=7    page=0    chnl=0
+char id=178   x=230  y=23   width=3    height=3    xoffset=-1   yoffset=3    xadvance=4    page=0    chnl=0
+char id=179   x=225  y=23   width=3    height=3    xoffset=-1   yoffset=3    xadvance=4    page=0    chnl=0
+char id=180   x=220  y=23   width=3    height=3    xoffset=-1   yoffset=3    xadvance=4    page=0    chnl=0
+char id=181   x=47   y=14   width=5    height=7    xoffset=-1   yoffset=6    xadvance=7    page=0    chnl=0
+char id=182   x=39   y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=183   x=292  y=23   width=2    height=1    xoffset=-1   yoffset=8    xadvance=3    page=0    chnl=0
+char id=184   x=215  y=23   width=3    height=3    xoffset=-1   yoffset=10   xadvance=4    page=0    chnl=0
+char id=185   x=211  y=23   width=2    height=3    xoffset=-1   yoffset=3    xadvance=4    page=0    chnl=0
+char id=186   x=205  y=23   width=4    height=3    xoffset=-1   yoffset=5    xadvance=5    page=0    chnl=0
+char id=187   x=31   y=23   width=5    height=5    xoffset=-1   yoffset=6    xadvance=6    page=0    chnl=0
+char id=188   x=184  y=2    width=5    height=9    xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=189   x=191  y=2    width=5    height=9    xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=190   x=198  y=2    width=6    height=9    xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=191   x=472  y=2    width=5    height=7    xoffset=-1   yoffset=6    xadvance=5    page=0    chnl=0
+char id=192   x=16   y=2    width=6    height=10   xoffset=-1   yoffset=1    xadvance=7    page=0    chnl=0
+char id=193   x=24   y=2    width=6    height=10   xoffset=-1   yoffset=1    xadvance=7    page=0    chnl=0
+char id=194   x=213  y=2    width=6    height=9    xoffset=-1   yoffset=2    xadvance=7    page=0    chnl=0
+char id=195   x=221  y=2    width=6    height=9    xoffset=-1   yoffset=2    xadvance=7    page=0    chnl=0
+char id=196   x=229  y=2    width=6    height=9    xoffset=-1   yoffset=2    xadvance=7    page=0    chnl=0
+char id=197   x=237  y=2    width=6    height=9    xoffset=-1   yoffset=2    xadvance=7    page=0    chnl=0
+char id=198   x=149  y=14   width=9    height=7    xoffset=-1   yoffset=4    xadvance=10   page=0    chnl=0
+char id=199   x=245  y=2    width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=200   x=39   y=2    width=6    height=10   xoffset=-1   yoffset=1    xadvance=7    page=0    chnl=0
+char id=201   x=47   y=2    width=6    height=10   xoffset=-1   yoffset=1    xadvance=7    page=0    chnl=0
+char id=202   x=253  y=2    width=6    height=9    xoffset=-1   yoffset=2    xadvance=7    page=0    chnl=0
+char id=203   x=261  y=2    width=6    height=9    xoffset=-1   yoffset=2    xadvance=7    page=0    chnl=0
+char id=204   x=55   y=2    width=4    height=10   xoffset=-2   yoffset=1    xadvance=3    page=0    chnl=0
+char id=205   x=61   y=2    width=3    height=10   xoffset=-1   yoffset=1    xadvance=3    page=0    chnl=0
+char id=206   x=285  y=2    width=4    height=9    xoffset=-2   yoffset=2    xadvance=3    page=0    chnl=0
+char id=207   x=291  y=2    width=4    height=9    xoffset=-2   yoffset=2    xadvance=3    page=0    chnl=0
+char id=208   x=414  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=209   x=297  y=2    width=6    height=9    xoffset=-1   yoffset=2    xadvance=8    page=0    chnl=0
+char id=210   x=66   y=2    width=7    height=10   xoffset=-1   yoffset=1    xadvance=8    page=0    chnl=0
+char id=211   x=75   y=2    width=7    height=10   xoffset=-1   yoffset=1    xadvance=8    page=0    chnl=0
+char id=212   x=305  y=2    width=7    height=9    xoffset=-1   yoffset=2    xadvance=8    page=0    chnl=0
+char id=213   x=323  y=2    width=7    height=9    xoffset=-1   yoffset=2    xadvance=8    page=0    chnl=0
+char id=214   x=314  y=2    width=7    height=9    xoffset=-1   yoffset=2    xadvance=8    page=0    chnl=0
+char id=215   x=81   y=23   width=5    height=5    xoffset=-1   yoffset=6    xadvance=7    page=0    chnl=0
+char id=216   x=84   y=2    width=7    height=10   xoffset=-1   yoffset=3    xadvance=8    page=0    chnl=0
+char id=217   x=93   y=2    width=6    height=10   xoffset=-1   yoffset=1    xadvance=7    page=0    chnl=0
+char id=218   x=101  y=2    width=6    height=10   xoffset=-1   yoffset=1    xadvance=7    page=0    chnl=0
+char id=219   x=277  y=2    width=6    height=9    xoffset=-1   yoffset=2    xadvance=7    page=0    chnl=0
+char id=220   x=269  y=2    width=6    height=9    xoffset=-1   yoffset=2    xadvance=7    page=0    chnl=0
+char id=221   x=109  y=2    width=6    height=10   xoffset=-1   yoffset=1    xadvance=6    page=0    chnl=0
+char id=222   x=474  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=223   x=486  y=2    width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=224   x=436  y=2    width=5    height=8    xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=225   x=429  y=2    width=5    height=8    xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=226   x=451  y=2    width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=227   x=465  y=2    width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=228   x=479  y=2    width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=229   x=422  y=2    width=5    height=8    xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=230   x=21   y=23   width=8    height=5    xoffset=-1   yoffset=6    xadvance=9    page=0    chnl=0
+char id=231   x=160  y=14   width=4    height=7    xoffset=-1   yoffset=6    xadvance=5    page=0    chnl=0
+char id=232   x=408  y=2    width=5    height=8    xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=233   x=360  y=2    width=5    height=8    xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=234   x=429  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=235   x=422  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=236   x=349  y=2    width=3    height=8    xoffset=-2   yoffset=3    xadvance=3    page=0    chnl=0
+char id=237   x=344  y=2    width=3    height=8    xoffset=-1   yoffset=3    xadvance=3    page=0    chnl=0
+char id=238   x=408  y=14   width=4    height=7    xoffset=-2   yoffset=4    xadvance=3    page=0    chnl=0
+char id=239   x=402  y=14   width=4    height=7    xoffset=-2   yoffset=4    xadvance=3    page=0    chnl=0
+char id=240   x=337  y=2    width=5    height=8    xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=241   x=119  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=242   x=394  y=2    width=5    height=8    xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=243   x=387  y=2    width=5    height=8    xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=244   x=443  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=245   x=436  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=246   x=62   y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=247   x=194  y=23   width=5    height=4    xoffset=-1   yoffset=7    xadvance=7    page=0    chnl=0
+char id=248   x=373  y=2    width=5    height=8    xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=249   x=380  y=2    width=5    height=8    xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=250   x=401  y=2    width=5    height=8    xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=251   x=459  y=14   width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=252   x=458  y=2    width=5    height=7    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=253   x=32   y=2    width=5    height=10   xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=254   x=206  y=2    width=5    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=255   x=173  y=2    width=5    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=8226  x=253  y=23   width=3    height=3    xoffset=0    yoffset=7    xadvance=6    page=0    chnl=0
+char id=8364  x=482  y=14   width=6    height=7    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+kernings count=0

+ 198 - 0
assets/ui/font-subtitle.fnt

@@ -0,0 +1,198 @@
+info face="font-subtitle" size=12 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=2 padding=1,1,1,1 spacing=0,0
+common lineHeight=18 base=13 scaleW=505 scaleH=36 pages=1 packed=0 alphaChnl=0 redChnl=0 greenChnl=0 blueChnl=0
+page id=0 file="font-subtitle.png"
+chars count=193
+char id=0     x=0    y=0    width=0    height=0    xoffset=-1   yoffset=13   xadvance=3    page=0    chnl=0
+char id=32    x=0    y=0    width=0    height=0    xoffset=-1   yoffset=-1   xadvance=3    page=0    chnl=0
+char id=33    x=9    y=27   width=1    height=8    xoffset=0    yoffset=5    xadvance=3    page=0    chnl=0
+char id=34    x=351  y=27   width=4    height=3    xoffset=-1   yoffset=5    xadvance=4    page=0    chnl=0
+char id=35    x=46   y=27   width=7    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=36    x=7    y=2    width=6    height=12   xoffset=-1   yoffset=3    xadvance=7    page=0    chnl=0
+char id=37    x=117  y=16   width=7    height=9    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=38    x=28   y=27   width=8    height=8    xoffset=-1   yoffset=5    xadvance=8    page=0    chnl=0
+char id=39    x=370  y=27   width=2    height=3    xoffset=-1   yoffset=5    xadvance=2    page=0    chnl=0
+char id=40    x=39   y=2    width=3    height=11   xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=41    x=44   y=2    width=3    height=11   xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=42    x=270  y=27   width=5    height=5    xoffset=-1   yoffset=4    xadvance=5    page=0    chnl=0
+char id=43    x=164  y=27   width=7    height=6    xoffset=-1   yoffset=7    xadvance=7    page=0    chnl=0
+char id=44    x=379  y=27   width=2    height=3    xoffset=-1   yoffset=11   xadvance=2    page=0    chnl=0
+char id=45    x=410  y=27   width=5    height=1    xoffset=-1   yoffset=9    xadvance=6    page=0    chnl=0
+char id=46    x=436  y=27   width=2    height=1    xoffset=-1   yoffset=12   xadvance=2    page=0    chnl=0
+char id=47    x=341  y=2    width=5    height=10   xoffset=-1   yoffset=4    xadvance=5    page=0    chnl=0
+char id=48    x=0    y=27   width=7    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=49    x=441  y=16   width=4    height=8    xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=50    x=447  y=16   width=6    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=51    x=455  y=16   width=6    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=52    x=463  y=16   width=7    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=53    x=472  y=16   width=6    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=54    x=480  y=16   width=7    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=55    x=55   y=16   width=5    height=9    xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=56    x=489  y=16   width=7    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=57    x=498  y=16   width=6    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=58    x=277  y=27   width=2    height=5    xoffset=-1   yoffset=8    xadvance=2    page=0    chnl=0
+char id=59    x=112  y=27   width=2    height=7    xoffset=-1   yoffset=8    xadvance=3    page=0    chnl=0
+char id=60    x=148  y=27   width=6    height=6    xoffset=-1   yoffset=7    xadvance=7    page=0    chnl=0
+char id=61    x=362  y=27   width=6    height=3    xoffset=-1   yoffset=9    xadvance=7    page=0    chnl=0
+char id=62    x=139  y=27   width=7    height=6    xoffset=-1   yoffset=7    xadvance=7    page=0    chnl=0
+char id=63    x=12   y=27   width=5    height=8    xoffset=-1   yoffset=5    xadvance=5    page=0    chnl=0
+char id=64    x=348  y=2    width=12   height=10   xoffset=-1   yoffset=5    xadvance=12   page=0    chnl=0
+char id=65    x=145  y=16   width=7    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=66    x=154  y=16   width=6    height=8    xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=67    x=162  y=16   width=7    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=68    x=171  y=16   width=7    height=8    xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=69    x=180  y=16   width=6    height=8    xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=70    x=188  y=16   width=5    height=8    xoffset=0    yoffset=5    xadvance=6    page=0    chnl=0
+char id=71    x=212  y=16   width=7    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=72    x=228  y=16   width=6    height=8    xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=73    x=236  y=16   width=1    height=8    xoffset=0    yoffset=5    xadvance=3    page=0    chnl=0
+char id=74    x=379  y=2    width=3    height=9    xoffset=-1   yoffset=5    xadvance=3    page=0    chnl=0
+char id=75    x=249  y=16   width=6    height=8    xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=76    x=257  y=16   width=5    height=8    xoffset=0    yoffset=5    xadvance=6    page=0    chnl=0
+char id=77    x=264  y=16   width=8    height=8    xoffset=0    yoffset=5    xadvance=10   page=0    chnl=0
+char id=78    x=274  y=16   width=6    height=8    xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=79    x=282  y=16   width=8    height=8    xoffset=-1   yoffset=5    xadvance=8    page=0    chnl=0
+char id=80    x=292  y=16   width=6    height=8    xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=81    x=323  y=2    width=8    height=10   xoffset=-1   yoffset=5    xadvance=8    page=0    chnl=0
+char id=82    x=300  y=16   width=6    height=8    xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=83    x=308  y=16   width=6    height=8    xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=84    x=316  y=16   width=7    height=8    xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=85    x=325  y=16   width=6    height=8    xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=86    x=333  y=16   width=7    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=87    x=342  y=16   width=10   height=8    xoffset=-1   yoffset=5    xadvance=10   page=0    chnl=0
+char id=88    x=354  y=16   width=7    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=89    x=363  y=16   width=7    height=8    xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=90    x=372  y=16   width=6    height=8    xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=91    x=49   y=2    width=3    height=11   xoffset=0    yoffset=4    xadvance=4    page=0    chnl=0
+char id=92    x=102  y=16   width=5    height=9    xoffset=-1   yoffset=4    xadvance=5    page=0    chnl=0
+char id=93    x=54   y=2    width=3    height=11   xoffset=-1   yoffset=4    xadvance=4    page=0    chnl=0
+char id=94    x=310  y=27   width=6    height=4    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=95    x=417  y=27   width=6    height=1    xoffset=0    yoffset=14   xadvance=8    page=0    chnl=0
+char id=96    x=388  y=27   width=3    height=2    xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=97    x=124  y=27   width=6    height=6    xoffset=-1   yoffset=7    xadvance=6    page=0    chnl=0
+char id=98    x=384  y=2    width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=99    x=132  y=27   width=5    height=6    xoffset=-1   yoffset=7    xadvance=5    page=0    chnl=0
+char id=100   x=392  y=2    width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=101   x=156  y=27   width=6    height=6    xoffset=-1   yoffset=7    xadvance=6    page=0    chnl=0
+char id=102   x=400  y=2    width=4    height=9    xoffset=-1   yoffset=4    xadvance=4    page=0    chnl=0
+char id=103   x=414  y=2    width=6    height=9    xoffset=-1   yoffset=7    xadvance=6    page=0    chnl=0
+char id=104   x=453  y=2    width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=105   x=416  y=16   width=2    height=8    xoffset=-1   yoffset=5    xadvance=2    page=0    chnl=0
+char id=106   x=34   y=2    width=3    height=11   xoffset=-2   yoffset=5    xadvance=2    page=0    chnl=0
+char id=107   x=494  y=2    width=6    height=9    xoffset=-1   yoffset=4    xadvance=5    page=0    chnl=0
+char id=108   x=502  y=2    width=1    height=9    xoffset=0    yoffset=4    xadvance=2    page=0    chnl=0
+char id=109   x=185  y=27   width=10   height=6    xoffset=-1   yoffset=7    xadvance=10   page=0    chnl=0
+char id=110   x=197  y=27   width=6    height=6    xoffset=-1   yoffset=7    xadvance=6    page=0    chnl=0
+char id=111   x=205  y=27   width=6    height=6    xoffset=-1   yoffset=7    xadvance=6    page=0    chnl=0
+char id=112   x=31   y=16   width=6    height=9    xoffset=-1   yoffset=7    xadvance=6    page=0    chnl=0
+char id=113   x=39   y=16   width=6    height=9    xoffset=-1   yoffset=7    xadvance=6    page=0    chnl=0
+char id=114   x=106  y=27   width=4    height=7    xoffset=-1   yoffset=6    xadvance=4    page=0    chnl=0
+char id=115   x=213  y=27   width=5    height=6    xoffset=-1   yoffset=7    xadvance=6    page=0    chnl=0
+char id=116   x=434  y=16   width=5    height=8    xoffset=-1   yoffset=5    xadvance=4    page=0    chnl=0
+char id=117   x=220  y=27   width=6    height=6    xoffset=-1   yoffset=7    xadvance=6    page=0    chnl=0
+char id=118   x=228  y=27   width=6    height=6    xoffset=-1   yoffset=7    xadvance=6    page=0    chnl=0
+char id=119   x=236  y=27   width=9    height=6    xoffset=-1   yoffset=7    xadvance=9    page=0    chnl=0
+char id=120   x=247  y=27   width=5    height=6    xoffset=-1   yoffset=7    xadvance=5    page=0    chnl=0
+char id=121   x=47   y=16   width=6    height=9    xoffset=-1   yoffset=7    xadvance=6    page=0    chnl=0
+char id=122   x=254  y=27   width=5    height=6    xoffset=-1   yoffset=7    xadvance=5    page=0    chnl=0
+char id=123   x=59   y=2    width=4    height=11   xoffset=-1   yoffset=4    xadvance=4    page=0    chnl=0
+char id=124   x=4    y=2    width=1    height=12   xoffset=0    yoffset=4    xadvance=2    page=0    chnl=0
+char id=125   x=65   y=2    width=4    height=11   xoffset=-1   yoffset=4    xadvance=4    page=0    chnl=0
+char id=126   x=393  y=27   width=6    height=2    xoffset=-1   yoffset=9    xadvance=7    page=0    chnl=0
+char id=160   x=0    y=0    width=0    height=0    xoffset=-1   yoffset=13   xadvance=3    page=0    chnl=0
+char id=161   x=126  y=16   width=2    height=9    xoffset=-1   yoffset=7    xadvance=2    page=0    chnl=0
+char id=162   x=130  y=16   width=5    height=9    xoffset=0    yoffset=6    xadvance=7    page=0    chnl=0
+char id=163   x=221  y=16   width=5    height=8    xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=164   x=89   y=27   width=6    height=7    xoffset=-1   yoffset=6    xadvance=7    page=0    chnl=0
+char id=165   x=203  y=16   width=7    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=166   x=15   y=2    width=1    height=12   xoffset=0    yoffset=4    xadvance=3    page=0    chnl=0
+char id=167   x=362  y=2    width=6    height=10   xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=168   x=425  y=27   width=3    height=1    xoffset=-1   yoffset=5    xadvance=3    page=0    chnl=0
+char id=169   x=80   y=27   width=7    height=7    xoffset=-1   yoffset=4    xadvance=8    page=0    chnl=0
+char id=170   x=298  y=27   width=4    height=4    xoffset=-1   yoffset=5    xadvance=4    page=0    chnl=0
+char id=171   x=290  y=27   width=6    height=4    xoffset=-1   yoffset=8    xadvance=6    page=0    chnl=0
+char id=172   x=338  y=27   width=6    height=3    xoffset=-1   yoffset=9    xadvance=7    page=0    chnl=0
+char id=174   x=97   y=27   width=7    height=7    xoffset=-1   yoffset=4    xadvance=8    page=0    chnl=0
+char id=175   x=430  y=27   width=4    height=1    xoffset=-2   yoffset=5    xadvance=3    page=0    chnl=0
+char id=176   x=304  y=27   width=4    height=4    xoffset=0    yoffset=4    xadvance=7    page=0    chnl=0
+char id=177   x=281  y=27   width=7    height=5    xoffset=-1   yoffset=7    xadvance=7    page=0    chnl=0
+char id=178   x=383  y=27   width=3    height=3    xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=179   x=346  y=27   width=3    height=3    xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=180   x=401  y=27   width=3    height=2    xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=181   x=78   y=16   width=5    height=9    xoffset=0    yoffset=7    xadvance=7    page=0    chnl=0
+char id=182   x=19   y=27   width=7    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=183   x=406  y=27   width=2    height=1    xoffset=-1   yoffset=9    xadvance=2    page=0    chnl=0
+char id=184   x=357  y=27   width=3    height=3    xoffset=-1   yoffset=13   xadvance=3    page=0    chnl=0
+char id=185   x=374  y=27   width=3    height=3    xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=186   x=332  y=27   width=4    height=4    xoffset=-1   yoffset=5    xadvance=4    page=0    chnl=0
+char id=187   x=324  y=27   width=6    height=4    xoffset=-1   yoffset=8    xadvance=6    page=0    chnl=0
+char id=188   x=79   y=2    width=6    height=11   xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=189   x=87   y=2    width=6    height=11   xoffset=-1   yoffset=3    xadvance=6    page=0    chnl=0
+char id=190   x=95   y=2    width=7    height=11   xoffset=-1   yoffset=3    xadvance=7    page=0    chnl=0
+char id=191   x=8    y=16   width=5    height=9    xoffset=-1   yoffset=7    xadvance=5    page=0    chnl=0
+char id=192   x=104  y=2    width=7    height=11   xoffset=-1   yoffset=2    xadvance=7    page=0    chnl=0
+char id=193   x=113  y=2    width=7    height=11   xoffset=-1   yoffset=2    xadvance=7    page=0    chnl=0
+char id=194   x=122  y=2    width=7    height=11   xoffset=-1   yoffset=2    xadvance=7    page=0    chnl=0
+char id=195   x=131  y=2    width=7    height=11   xoffset=-1   yoffset=2    xadvance=7    page=0    chnl=0
+char id=196   x=140  y=2    width=7    height=11   xoffset=-1   yoffset=2    xadvance=7    page=0    chnl=0
+char id=197   x=370  y=2    width=7    height=10   xoffset=-1   yoffset=3    xadvance=7    page=0    chnl=0
+char id=198   x=404  y=16   width=10   height=8    xoffset=-1   yoffset=5    xadvance=11   page=0    chnl=0
+char id=199   x=149  y=2    width=7    height=11   xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=200   x=158  y=2    width=6    height=11   xoffset=0    yoffset=2    xadvance=7    page=0    chnl=0
+char id=201   x=166  y=2    width=6    height=11   xoffset=0    yoffset=2    xadvance=7    page=0    chnl=0
+char id=202   x=174  y=2    width=6    height=11   xoffset=0    yoffset=2    xadvance=7    page=0    chnl=0
+char id=203   x=182  y=2    width=6    height=11   xoffset=0    yoffset=2    xadvance=7    page=0    chnl=0
+char id=204   x=190  y=2    width=4    height=11   xoffset=-2   yoffset=2    xadvance=3    page=0    chnl=0
+char id=205   x=196  y=2    width=3    height=11   xoffset=-1   yoffset=2    xadvance=3    page=0    chnl=0
+char id=206   x=201  y=2    width=5    height=11   xoffset=-2   yoffset=2    xadvance=3    page=0    chnl=0
+char id=207   x=208  y=2    width=4    height=11   xoffset=-2   yoffset=2    xadvance=3    page=0    chnl=0
+char id=208   x=239  y=16   width=8    height=8    xoffset=-1   yoffset=5    xadvance=8    page=0    chnl=0
+char id=209   x=214  y=2    width=6    height=11   xoffset=0    yoffset=2    xadvance=8    page=0    chnl=0
+char id=210   x=222  y=2    width=8    height=11   xoffset=-1   yoffset=2    xadvance=8    page=0    chnl=0
+char id=211   x=232  y=2    width=8    height=11   xoffset=-1   yoffset=2    xadvance=8    page=0    chnl=0
+char id=212   x=242  y=2    width=8    height=11   xoffset=-1   yoffset=2    xadvance=8    page=0    chnl=0
+char id=213   x=252  y=2    width=8    height=11   xoffset=-1   yoffset=2    xadvance=8    page=0    chnl=0
+char id=214   x=262  y=2    width=8    height=11   xoffset=-1   yoffset=2    xadvance=8    page=0    chnl=0
+char id=215   x=116  y=27   width=6    height=6    xoffset=-1   yoffset=7    xadvance=7    page=0    chnl=0
+char id=216   x=313  y=2    width=8    height=11   xoffset=-1   yoffset=4    xadvance=8    page=0    chnl=0
+char id=217   x=305  y=2    width=6    height=11   xoffset=0    yoffset=2    xadvance=8    page=0    chnl=0
+char id=218   x=297  y=2    width=6    height=11   xoffset=0    yoffset=2    xadvance=8    page=0    chnl=0
+char id=219   x=289  y=2    width=6    height=11   xoffset=0    yoffset=2    xadvance=8    page=0    chnl=0
+char id=220   x=281  y=2    width=6    height=11   xoffset=0    yoffset=2    xadvance=8    page=0    chnl=0
+char id=221   x=272  y=2    width=7    height=11   xoffset=-1   yoffset=2    xadvance=6    page=0    chnl=0
+char id=222   x=38   y=27   width=6    height=8    xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=223   x=85   y=16   width=7    height=9    xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=224   x=94   y=16   width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=225   x=137  y=16   width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=226   x=469  y=2    width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=227   x=380  y=16   width=6    height=8    xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=228   x=388  y=16   width=6    height=8    xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=229   x=406  y=2    width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=230   x=173  y=27   width=10   height=6    xoffset=-1   yoffset=7    xadvance=10   page=0    chnl=0
+char id=231   x=422  y=2    width=5    height=9    xoffset=-1   yoffset=7    xadvance=5    page=0    chnl=0
+char id=232   x=429  y=2    width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=233   x=437  y=2    width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=234   x=445  y=2    width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=235   x=396  y=16   width=6    height=8    xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=236   x=477  y=2    width=3    height=9    xoffset=-2   yoffset=4    xadvance=2    page=0    chnl=0
+char id=237   x=482  y=2    width=4    height=9    xoffset=-1   yoffset=4    xadvance=2    page=0    chnl=0
+char id=238   x=488  y=2    width=4    height=9    xoffset=-2   yoffset=4    xadvance=2    page=0    chnl=0
+char id=239   x=420  y=16   width=4    height=8    xoffset=-2   yoffset=5    xadvance=2    page=0    chnl=0
+char id=240   x=0    y=16   width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=241   x=426  y=16   width=6    height=8    xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=242   x=15   y=16   width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=243   x=23   y=16   width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=244   x=109  y=16   width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=245   x=63   y=27   width=6    height=8    xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=246   x=55   y=27   width=6    height=8    xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=247   x=261  y=27   width=7    height=5    xoffset=-1   yoffset=8    xadvance=7    page=0    chnl=0
+char id=248   x=333  y=2    width=6    height=10   xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=249   x=70   y=16   width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=250   x=62   y=16   width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=251   x=461  y=2    width=6    height=9    xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=252   x=195  y=16   width=6    height=8    xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=253   x=26   y=2    width=6    height=12   xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=254   x=18   y=2    width=6    height=12   xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=255   x=71   y=2    width=6    height=11   xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=8226  x=318  y=27   width=4    height=4    xoffset=0    yoffset=8    xadvance=6    page=0    chnl=0
+char id=8364  x=71   y=27   width=7    height=8    xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+kernings count=0

+ 198 - 0
assets/ui/font-window.fnt

@@ -0,0 +1,198 @@
+info face="font-window" size=12 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=2 padding=1,1,1,1 spacing=0,0
+common lineHeight=27 base=20 scaleW=506 scaleH=62 pages=1 packed=0 alphaChnl=0 redChnl=0 greenChnl=0 blueChnl=0
+page id=0 file="font-window.png"
+chars count=193
+char id=0     x=0    y=0    width=0    height=0    xoffset=-1   yoffset=20   xadvance=4    page=0    chnl=0
+char id=32    x=0    y=0    width=0    height=0    xoffset=-1   yoffset=-1   xadvance=4    page=0    chnl=0
+char id=33    x=276  y=38   width=2    height=12   xoffset=0    yoffset=8    xadvance=4    page=0    chnl=0
+char id=34    x=293  y=52   width=5    height=4    xoffset=0    yoffset=8    xadvance=7    page=0    chnl=0
+char id=35    x=370  y=38   width=10   height=12   xoffset=0    yoffset=8    xadvance=12   page=0    chnl=0
+char id=36    x=175  y=2    width=8    height=16   xoffset=0    yoffset=6    xadvance=10   page=0    chnl=0
+char id=37    x=62   y=22   width=10   height=14   xoffset=0    yoffset=7    xadvance=12   page=0    chnl=0
+char id=38    x=343  y=38   width=13   height=12   xoffset=0    yoffset=8    xadvance=13   page=0    chnl=0
+char id=39    x=306  y=52   width=2    height=4    xoffset=0    yoffset=8    xadvance=4    page=0    chnl=0
+char id=40    x=392  y=2    width=4    height=15   xoffset=0    yoffset=7    xadvance=5    page=0    chnl=0
+char id=41    x=398  y=2    width=4    height=15   xoffset=-1   yoffset=7    xadvance=5    page=0    chnl=0
+char id=42    x=172  y=52   width=7    height=8    xoffset=-1   yoffset=6    xadvance=8    page=0    chnl=0
+char id=43    x=465  y=38   width=8    height=9    xoffset=0    yoffset=11   xadvance=10   page=0    chnl=0
+char id=44    x=300  y=52   width=4    height=4    xoffset=-1   yoffset=18   xadvance=5    page=0    chnl=0
+char id=45    x=359  y=52   width=5    height=2    xoffset=0    yoffset=14   xadvance=7    page=0    chnl=0
+char id=46    x=330  y=52   width=2    height=3    xoffset=0    yoffset=17   xadvance=4    page=0    chnl=0
+char id=47    x=0    y=22   width=8    height=14   xoffset=-1   yoffset=7    xadvance=8    page=0    chnl=0
+char id=48    x=265  y=38   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=49    x=174  y=38   width=6    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=50    x=182  y=38   width=7    height=12   xoffset=0    yoffset=8    xadvance=9    page=0    chnl=0
+char id=51    x=191  y=38   width=8    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=52    x=201  y=38   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=53    x=212  y=38   width=9    height=12   xoffset=-1   yoffset=8    xadvance=10   page=0    chnl=0
+char id=54    x=223  y=38   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=55    x=234  y=38   width=7    height=12   xoffset=0    yoffset=8    xadvance=9    page=0    chnl=0
+char id=56    x=243  y=38   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=57    x=254  y=38   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=58    x=192  y=52   width=2    height=8    xoffset=0    yoffset=12   xadvance=4    page=0    chnl=0
+char id=59    x=444  y=38   width=4    height=10   xoffset=-1   yoffset=12   xadvance=4    page=0    chnl=0
+char id=60    x=0    y=52   width=8    height=9    xoffset=0    yoffset=11   xadvance=10   page=0    chnl=0
+char id=61    x=204  y=52   width=8    height=6    xoffset=0    yoffset=12   xadvance=10   page=0    chnl=0
+char id=62    x=495  y=38   width=8    height=9    xoffset=1    yoffset=11   xadvance=11   page=0    chnl=0
+char id=63    x=280  y=38   width=7    height=12   xoffset=-1   yoffset=8    xadvance=8    page=0    chnl=0
+char id=64    x=157  y=2    width=16   height=16   xoffset=0    yoffset=8    xadvance=18   page=0    chnl=0
+char id=65    x=303  y=22   width=11   height=12   xoffset=-1   yoffset=8    xadvance=11   page=0    chnl=0
+char id=66    x=316  y=22   width=8    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=67    x=326  y=22   width=8    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=68    x=336  y=22   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=69    x=347  y=22   width=8    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=70    x=357  y=22   width=8    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=71    x=367  y=22   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=72    x=378  y=22   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=73    x=389  y=22   width=2    height=12   xoffset=0    yoffset=8    xadvance=4    page=0    chnl=0
+char id=74    x=122  y=22   width=4    height=13   xoffset=-1   yoffset=8    xadvance=5    page=0    chnl=0
+char id=75    x=393  y=22   width=9    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=76    x=404  y=22   width=7    height=12   xoffset=0    yoffset=8    xadvance=9    page=0    chnl=0
+char id=77    x=413  y=22   width=13   height=12   xoffset=0    yoffset=8    xadvance=15   page=0    chnl=0
+char id=78    x=440  y=22   width=10   height=12   xoffset=0    yoffset=8    xadvance=12   page=0    chnl=0
+char id=79    x=462  y=22   width=10   height=12   xoffset=0    yoffset=8    xadvance=12   page=0    chnl=0
+char id=80    x=478  y=22   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=81    x=380  y=2    width=10   height=15   xoffset=0    yoffset=8    xadvance=12   page=0    chnl=0
+char id=82    x=0    y=38   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=83    x=11   y=38   width=8    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=84    x=21   y=38   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=85    x=32   y=38   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=86    x=43   y=38   width=11   height=12   xoffset=-1   yoffset=8    xadvance=11   page=0    chnl=0
+char id=87    x=56   y=38   width=17   height=12   xoffset=-1   yoffset=8    xadvance=17   page=0    chnl=0
+char id=88    x=75   y=38   width=11   height=12   xoffset=-1   yoffset=8    xadvance=10   page=0    chnl=0
+char id=89    x=88   y=38   width=10   height=12   xoffset=-1   yoffset=8    xadvance=10   page=0    chnl=0
+char id=90    x=100  y=38   width=8    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=91    x=404  y=2    width=5    height=15   xoffset=0    yoffset=7    xadvance=6    page=0    chnl=0
+char id=92    x=10   y=22   width=9    height=14   xoffset=-1   yoffset=7    xadvance=9    page=0    chnl=0
+char id=93    x=411  y=2    width=4    height=15   xoffset=0    yoffset=7    xadvance=6    page=0    chnl=0
+char id=94    x=222  y=52   width=10   height=6    xoffset=-1   yoffset=8    xadvance=10   page=0    chnl=0
+char id=95    x=349  y=52   width=8    height=2    xoffset=1    yoffset=21   xadvance=12   page=0    chnl=0
+char id=96    x=279  y=52   width=6    height=5    xoffset=-2   yoffset=6    xadvance=5    page=0    chnl=0
+char id=97    x=32   y=52   width=8    height=9    xoffset=0    yoffset=11   xadvance=10   page=0    chnl=0
+char id=98    x=110  y=38   width=8    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=99    x=42   y=52   width=7    height=9    xoffset=0    yoffset=11   xadvance=8    page=0    chnl=0
+char id=100   x=120  y=38   width=8    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=101   x=51   y=52   width=8    height=9    xoffset=0    yoffset=11   xadvance=10   page=0    chnl=0
+char id=102   x=130  y=38   width=6    height=12   xoffset=0    yoffset=8    xadvance=8    page=0    chnl=0
+char id=103   x=158  y=22   width=8    height=13   xoffset=0    yoffset=11   xadvance=10   page=0    chnl=0
+char id=104   x=138  y=38   width=8    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=105   x=148  y=38   width=2    height=12   xoffset=0    yoffset=8    xadvance=4    page=0    chnl=0
+char id=106   x=147  y=2    width=4    height=16   xoffset=-2   yoffset=8    xadvance=4    page=0    chnl=0
+char id=107   x=152  y=38   width=8    height=12   xoffset=0    yoffset=8    xadvance=9    page=0    chnl=0
+char id=108   x=162  y=38   width=2    height=12   xoffset=0    yoffset=8    xadvance=4    page=0    chnl=0
+char id=109   x=61   y=52   width=12   height=9    xoffset=0    yoffset=11   xadvance=14   page=0    chnl=0
+char id=110   x=75   y=52   width=8    height=9    xoffset=0    yoffset=11   xadvance=10   page=0    chnl=0
+char id=111   x=85   y=52   width=8    height=9    xoffset=0    yoffset=11   xadvance=10   page=0    chnl=0
+char id=112   x=215  y=22   width=8    height=13   xoffset=0    yoffset=11   xadvance=10   page=0    chnl=0
+char id=113   x=225  y=22   width=8    height=13   xoffset=0    yoffset=11   xadvance=10   page=0    chnl=0
+char id=114   x=436  y=38   width=6    height=10   xoffset=0    yoffset=10   xadvance=7    page=0    chnl=0
+char id=115   x=95   y=52   width=7    height=9    xoffset=0    yoffset=11   xadvance=9    page=0    chnl=0
+char id=116   x=166  y=38   width=6    height=12   xoffset=0    yoffset=8    xadvance=8    page=0    chnl=0
+char id=117   x=104  y=52   width=8    height=9    xoffset=0    yoffset=11   xadvance=10   page=0    chnl=0
+char id=118   x=114  y=52   width=9    height=9    xoffset=-1   yoffset=11   xadvance=9    page=0    chnl=0
+char id=119   x=125  y=52   width=14   height=9    xoffset=-1   yoffset=11   xadvance=14   page=0    chnl=0
+char id=120   x=141  y=52   width=9    height=9    xoffset=-1   yoffset=11   xadvance=9    page=0    chnl=0
+char id=121   x=235  y=22   width=9    height=13   xoffset=-1   yoffset=11   xadvance=9    page=0    chnl=0
+char id=122   x=152  y=52   width=7    height=9    xoffset=0    yoffset=11   xadvance=9    page=0    chnl=0
+char id=123   x=417  y=2    width=6    height=15   xoffset=0    yoffset=7    xadvance=7    page=0    chnl=0
+char id=124   x=153  y=2    width=2    height=16   xoffset=0    yoffset=8    xadvance=4    page=0    chnl=0
+char id=125   x=425  y=2    width=6    height=15   xoffset=0    yoffset=7    xadvance=7    page=0    chnl=0
+char id=126   x=320  y=52   width=8    height=3    xoffset=0    yoffset=14   xadvance=10   page=0    chnl=0
+char id=160   x=0    y=0    width=0    height=0    xoffset=-1   yoffset=20   xadvance=4    page=0    chnl=0
+char id=161   x=474  y=22   width=2    height=12   xoffset=0    yoffset=11   xadvance=4    page=0    chnl=0
+char id=162   x=403  y=38   width=7    height=11   xoffset=1    yoffset=10   xadvance=10   page=0    chnl=0
+char id=163   x=452  y=22   width=8    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=164   x=21   y=52   width=9    height=9    xoffset=-1   yoffset=11   xadvance=9    page=0    chnl=0
+char id=165   x=428  y=22   width=10   height=12   xoffset=-1   yoffset=8    xadvance=10   page=0    chnl=0
+char id=166   x=185  y=2    width=2    height=16   xoffset=0    yoffset=8    xadvance=4    page=0    chnl=0
+char id=167   x=433  y=2    width=8    height=15   xoffset=0    yoffset=9    xadvance=10   page=0    chnl=0
+char id=168   x=341  y=52   width=6    height=2    xoffset=-1   yoffset=8    xadvance=5    page=0    chnl=0
+char id=169   x=424  y=38   width=10   height=10   xoffset=0    yoffset=7    xadvance=12   page=0    chnl=0
+char id=170   x=250  y=52   width=6    height=5    xoffset=0    yoffset=8    xadvance=8    page=0    chnl=0
+char id=171   x=161  y=52   width=9    height=8    xoffset=0    yoffset=12   xadvance=11   page=0    chnl=0
+char id=172   x=240  y=52   width=8    height=5    xoffset=0    yoffset=14   xadvance=10   page=0    chnl=0
+char id=174   x=412  y=38   width=10   height=10   xoffset=0    yoffset=7    xadvance=12   page=0    chnl=0
+char id=175   x=334  y=52   width=5    height=2    xoffset=-1   yoffset=8    xadvance=5    page=0    chnl=0
+char id=176   x=196  y=52   width=6    height=6    xoffset=1    yoffset=7    xadvance=10   page=0    chnl=0
+char id=177   x=485  y=38   width=8    height=9    xoffset=0    yoffset=11   xadvance=10   page=0    chnl=0
+char id=178   x=265  y=52   width=4    height=5    xoffset=0    yoffset=6    xadvance=6    page=0    chnl=0
+char id=179   x=234  y=52   width=4    height=5    xoffset=0    yoffset=6    xadvance=6    page=0    chnl=0
+char id=180   x=271  y=52   width=6    height=5    xoffset=-1   yoffset=6    xadvance=5    page=0    chnl=0
+char id=181   x=266  y=22   width=8    height=13   xoffset=0    yoffset=11   xadvance=10   page=0    chnl=0
+char id=182   x=321  y=38   width=10   height=12   xoffset=-1   yoffset=8    xadvance=11   page=0    chnl=0
+char id=183   x=316  y=52   width=2    height=3    xoffset=0    yoffset=14   xadvance=4    page=0    chnl=0
+char id=184   x=310  y=52   width=4    height=4    xoffset=-1   yoffset=20   xadvance=5    page=0    chnl=0
+char id=185   x=287  y=52   width=4    height=5    xoffset=-1   yoffset=6    xadvance=5    page=0    chnl=0
+char id=186   x=214  y=52   width=6    height=6    xoffset=0    yoffset=8    xadvance=8    page=0    chnl=0
+char id=187   x=181  y=52   width=9    height=8    xoffset=0    yoffset=12   xadvance=11   page=0    chnl=0
+char id=188   x=443  y=2    width=9    height=15   xoffset=-1   yoffset=7    xadvance=10   page=0    chnl=0
+char id=189   x=454  y=2    width=9    height=15   xoffset=-1   yoffset=7    xadvance=10   page=0    chnl=0
+char id=190   x=189  y=2    width=9    height=16   xoffset=-1   yoffset=6    xadvance=10   page=0    chnl=0
+char id=191   x=168  y=22   width=7    height=13   xoffset=0    yoffset=11   xadvance=8    page=0    chnl=0
+char id=192   x=27   y=2    width=11   height=17   xoffset=-1   yoffset=3    xadvance=11   page=0    chnl=0
+char id=193   x=40   y=2    width=11   height=17   xoffset=-1   yoffset=3    xadvance=11   page=0    chnl=0
+char id=194   x=222  y=2    width=11   height=16   xoffset=-1   yoffset=4    xadvance=11   page=0    chnl=0
+char id=195   x=235  y=2    width=11   height=16   xoffset=-1   yoffset=4    xadvance=11   page=0    chnl=0
+char id=196   x=248  y=2    width=12   height=16   xoffset=-2   yoffset=4    xadvance=10   page=0    chnl=0
+char id=197   x=465  y=2    width=12   height=15   xoffset=-1   yoffset=5    xadvance=12   page=0    chnl=0
+char id=198   x=489  y=22   width=15   height=12   xoffset=-1   yoffset=8    xadvance=16   page=0    chnl=0
+char id=199   x=262  y=2    width=8    height=16   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=200   x=53   y=2    width=8    height=17   xoffset=0    yoffset=3    xadvance=10   page=0    chnl=0
+char id=201   x=63   y=2    width=8    height=17   xoffset=0    yoffset=3    xadvance=10   page=0    chnl=0
+char id=202   x=272  y=2    width=8    height=16   xoffset=0    yoffset=4    xadvance=10   page=0    chnl=0
+char id=203   x=282  y=2    width=8    height=16   xoffset=0    yoffset=4    xadvance=10   page=0    chnl=0
+char id=204   x=73   y=2    width=6    height=17   xoffset=-2   yoffset=3    xadvance=4    page=0    chnl=0
+char id=205   x=81   y=2    width=6    height=17   xoffset=-2   yoffset=3    xadvance=4    page=0    chnl=0
+char id=206   x=292  y=2    width=8    height=16   xoffset=-3   yoffset=4    xadvance=4    page=0    chnl=0
+char id=207   x=302  y=2    width=6    height=16   xoffset=-1   yoffset=4    xadvance=6    page=0    chnl=0
+char id=208   x=358  y=38   width=10   height=12   xoffset=0    yoffset=8    xadvance=12   page=0    chnl=0
+char id=209   x=310  y=2    width=10   height=16   xoffset=0    yoffset=4    xadvance=12   page=0    chnl=0
+char id=210   x=89   y=2    width=10   height=17   xoffset=0    yoffset=3    xadvance=12   page=0    chnl=0
+char id=211   x=101  y=2    width=10   height=17   xoffset=0    yoffset=3    xadvance=12   page=0    chnl=0
+char id=212   x=322  y=2    width=10   height=16   xoffset=0    yoffset=4    xadvance=12   page=0    chnl=0
+char id=213   x=334  y=2    width=10   height=16   xoffset=0    yoffset=4    xadvance=12   page=0    chnl=0
+char id=214   x=346  y=2    width=10   height=16   xoffset=0    yoffset=4    xadvance=12   page=0    chnl=0
+char id=215   x=10   y=52   width=9    height=9    xoffset=0    yoffset=11   xadvance=10   page=0    chnl=0
+char id=216   x=4    y=2    width=10   height=18   xoffset=0    yoffset=5    xadvance=12   page=0    chnl=0
+char id=217   x=113  y=2    width=9    height=17   xoffset=0    yoffset=3    xadvance=11   page=0    chnl=0
+char id=218   x=124  y=2    width=9    height=17   xoffset=0    yoffset=3    xadvance=11   page=0    chnl=0
+char id=219   x=358  y=2    width=9    height=16   xoffset=0    yoffset=4    xadvance=11   page=0    chnl=0
+char id=220   x=369  y=2    width=9    height=16   xoffset=0    yoffset=4    xadvance=11   page=0    chnl=0
+char id=221   x=135  y=2    width=10   height=17   xoffset=-1   yoffset=3    xadvance=10   page=0    chnl=0
+char id=222   x=289  y=38   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=223   x=300  y=38   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=224   x=74   y=22   width=8    height=14   xoffset=0    yoffset=6    xadvance=10   page=0    chnl=0
+char id=225   x=84   y=22   width=8    height=14   xoffset=0    yoffset=6    xadvance=10   page=0    chnl=0
+char id=226   x=185  y=22   width=8    height=13   xoffset=0    yoffset=7    xadvance=10   page=0    chnl=0
+char id=227   x=333  y=38   width=8    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=228   x=256  y=22   width=8    height=13   xoffset=0    yoffset=7    xadvance=10   page=0    chnl=0
+char id=229   x=32   y=22   width=8    height=14   xoffset=0    yoffset=6    xadvance=10   page=0    chnl=0
+char id=230   x=450  y=38   width=13   height=9    xoffset=0    yoffset=11   xadvance=15   page=0    chnl=0
+char id=231   x=276  y=22   width=7    height=13   xoffset=0    yoffset=11   xadvance=8    page=0    chnl=0
+char id=232   x=94   y=22   width=8    height=14   xoffset=0    yoffset=6    xadvance=10   page=0    chnl=0
+char id=233   x=112  y=22   width=8    height=14   xoffset=0    yoffset=6    xadvance=10   page=0    chnl=0
+char id=234   x=128  y=22   width=8    height=13   xoffset=0    yoffset=7    xadvance=10   page=0    chnl=0
+char id=235   x=138  y=22   width=8    height=13   xoffset=0    yoffset=7    xadvance=10   page=0    chnl=0
+char id=236   x=104  y=22   width=6    height=14   xoffset=-3   yoffset=6    xadvance=4    page=0    chnl=0
+char id=237   x=499  y=2    width=6    height=14   xoffset=-1   yoffset=6    xadvance=4    page=0    chnl=0
+char id=238   x=177  y=22   width=6    height=13   xoffset=-2   yoffset=7    xadvance=4    page=0    chnl=0
+char id=239   x=285  y=22   width=6    height=13   xoffset=-2   yoffset=7    xadvance=4    page=0    chnl=0
+char id=240   x=21   y=22   width=9    height=14   xoffset=0    yoffset=6    xadvance=11   page=0    chnl=0
+char id=241   x=382  y=38   width=8    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=242   x=489  y=2    width=8    height=14   xoffset=0    yoffset=6    xadvance=10   page=0    chnl=0
+char id=243   x=479  y=2    width=8    height=14   xoffset=0    yoffset=6    xadvance=10   page=0    chnl=0
+char id=244   x=148  y=22   width=8    height=13   xoffset=0    yoffset=7    xadvance=10   page=0    chnl=0
+char id=245   x=311  y=38   width=8    height=12   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=246   x=246  y=22   width=8    height=13   xoffset=0    yoffset=7    xadvance=10   page=0    chnl=0
+char id=247   x=475  y=38   width=8    height=9    xoffset=0    yoffset=11   xadvance=10   page=0    chnl=0
+char id=248   x=205  y=22   width=8    height=13   xoffset=0    yoffset=9    xadvance=10   page=0    chnl=0
+char id=249   x=42   y=22   width=8    height=14   xoffset=0    yoffset=6    xadvance=10   page=0    chnl=0
+char id=250   x=52   y=22   width=8    height=14   xoffset=0    yoffset=6    xadvance=10   page=0    chnl=0
+char id=251   x=293  y=22   width=8    height=13   xoffset=0    yoffset=7    xadvance=10   page=0    chnl=0
+char id=252   x=195  y=22   width=8    height=13   xoffset=0    yoffset=7    xadvance=10   page=0    chnl=0
+char id=253   x=16   y=2    width=9    height=18   xoffset=-1   yoffset=6    xadvance=9    page=0    chnl=0
+char id=254   x=200  y=2    width=8    height=16   xoffset=0    yoffset=8    xadvance=10   page=0    chnl=0
+char id=255   x=210  y=2    width=10   height=16   xoffset=-2   yoffset=8    xadvance=8    page=0    chnl=0
+char id=8226  x=258  y=52   width=5    height=5    xoffset=1    yoffset=13   xadvance=9    page=0    chnl=0
+char id=8364  x=392  y=38   width=9    height=12   xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+kernings count=0

+ 198 - 0
assets/ui/font.fnt

@@ -0,0 +1,198 @@
+info face="font" size=12 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=2 padding=1,1,1,1 spacing=0,0
+common lineHeight=21 base=15 scaleW=504 scaleH=44 pages=1 packed=0 alphaChnl=0 redChnl=0 greenChnl=0 blueChnl=0
+page id=0 file="font.png"
+chars count=193
+char id=0     x=0    y=0    width=0    height=0    xoffset=-1   yoffset=15   xadvance=3    page=0    chnl=0
+char id=32    x=0    y=0    width=0    height=0    xoffset=-1   yoffset=-1   xadvance=3    page=0    chnl=0
+char id=33    x=393  y=18   width=1    height=10   xoffset=0    yoffset=5    xadvance=3    page=0    chnl=0
+char id=34    x=458  y=30   width=3    height=3    xoffset=0    yoffset=5    xadvance=5    page=0    chnl=0
+char id=35    x=101  y=30   width=8    height=9    xoffset=-1   yoffset=6    xadvance=8    page=0    chnl=0
+char id=36    x=142  y=2    width=6    height=13   xoffset=0    yoffset=4    xadvance=8    page=0    chnl=0
+char id=37    x=496  y=18   width=7    height=10   xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=38    x=0    y=30   width=9    height=10   xoffset=0    yoffset=5    xadvance=10   page=0    chnl=0
+char id=39    x=463  y=30   width=1    height=3    xoffset=0    yoffset=5    xadvance=3    page=0    chnl=0
+char id=40    x=272  y=2    width=3    height=12   xoffset=0    yoffset=5    xadvance=4    page=0    chnl=0
+char id=41    x=277  y=2    width=3    height=12   xoffset=-1   yoffset=5    xadvance=4    page=0    chnl=0
+char id=42    x=369  y=30   width=6    height=5    xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=43    x=315  y=30   width=7    height=7    xoffset=-1   yoffset=8    xadvance=7    page=0    chnl=0
+char id=44    x=435  y=30   width=3    height=3    xoffset=-1   yoffset=14   xadvance=3    page=0    chnl=0
+char id=45    x=497  y=30   width=5    height=1    xoffset=0    yoffset=11   xadvance=6    page=0    chnl=0
+char id=46    x=466  y=30   width=1    height=2    xoffset=0    yoffset=13   xadvance=3    page=0    chnl=0
+char id=47    x=446  y=2    width=6    height=11   xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=48    x=120  y=30   width=7    height=9    xoffset=0    yoffset=6    xadvance=9    page=0    chnl=0
+char id=49    x=41   y=30   width=4    height=9    xoffset=0    yoffset=6    xadvance=7    page=0    chnl=0
+char id=50    x=47   y=30   width=7    height=9    xoffset=-1   yoffset=6    xadvance=7    page=0    chnl=0
+char id=51    x=56   y=30   width=6    height=9    xoffset=0    yoffset=6    xadvance=8    page=0    chnl=0
+char id=52    x=64   y=30   width=8    height=9    xoffset=-1   yoffset=6    xadvance=8    page=0    chnl=0
+char id=53    x=74   y=30   width=7    height=9    xoffset=-1   yoffset=6    xadvance=8    page=0    chnl=0
+char id=54    x=83   y=30   width=7    height=9    xoffset=0    yoffset=6    xadvance=9    page=0    chnl=0
+char id=55    x=385  y=18   width=6    height=10   xoffset=0    yoffset=6    xadvance=8    page=0    chnl=0
+char id=56    x=92   y=30   width=7    height=9    xoffset=-1   yoffset=6    xadvance=8    page=0    chnl=0
+char id=57    x=111  y=30   width=7    height=9    xoffset=0    yoffset=6    xadvance=9    page=0    chnl=0
+char id=58    x=333  y=30   width=1    height=6    xoffset=0    yoffset=9    xadvance=3    page=0    chnl=0
+char id=59    x=164  y=30   width=3    height=8    xoffset=-1   yoffset=9    xadvance=3    page=0    chnl=0
+char id=60    x=214  y=30   width=6    height=7    xoffset=0    yoffset=8    xadvance=8    page=0    chnl=0
+char id=61    x=449  y=30   width=7    height=3    xoffset=-1   yoffset=10   xadvance=8    page=0    chnl=0
+char id=62    x=206  y=30   width=6    height=7    xoffset=0    yoffset=8    xadvance=8    page=0    chnl=0
+char id=63    x=396  y=18   width=6    height=10   xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=64    x=128  y=2    width=12   height=13   xoffset=0    yoffset=5    xadvance=14   page=0    chnl=0
+char id=65    x=0    y=18   width=8    height=10   xoffset=-1   yoffset=5    xadvance=8    page=0    chnl=0
+char id=66    x=18   y=18   width=7    height=10   xoffset=0    yoffset=5    xadvance=9    page=0    chnl=0
+char id=67    x=27   y=18   width=7    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=68    x=67   y=18   width=7    height=10   xoffset=0    yoffset=5    xadvance=9    page=0    chnl=0
+char id=69    x=76   y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=70    x=84   y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=71    x=92   y=18   width=7    height=10   xoffset=0    yoffset=5    xadvance=9    page=0    chnl=0
+char id=72    x=101  y=18   width=7    height=10   xoffset=0    yoffset=5    xadvance=9    page=0    chnl=0
+char id=73    x=128  y=18   width=1    height=10   xoffset=0    yoffset=5    xadvance=3    page=0    chnl=0
+char id=74    x=379  y=2    width=3    height=11   xoffset=-1   yoffset=5    xadvance=4    page=0    chnl=0
+char id=75    x=131  y=18   width=7    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=76    x=140  y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=77    x=148  y=18   width=9    height=10   xoffset=0    yoffset=5    xadvance=11   page=0    chnl=0
+char id=78    x=159  y=18   width=7    height=10   xoffset=0    yoffset=5    xadvance=9    page=0    chnl=0
+char id=79    x=168  y=18   width=8    height=10   xoffset=0    yoffset=5    xadvance=10   page=0    chnl=0
+char id=80    x=178  y=18   width=7    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=81    x=262  y=2    width=8    height=12   xoffset=0    yoffset=5    xadvance=10   page=0    chnl=0
+char id=82    x=195  y=18   width=8    height=10   xoffset=0    yoffset=5    xadvance=9    page=0    chnl=0
+char id=83    x=205  y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=84    x=213  y=18   width=7    height=10   xoffset=-1   yoffset=5    xadvance=7    page=0    chnl=0
+char id=85    x=222  y=18   width=7    height=10   xoffset=0    yoffset=5    xadvance=9    page=0    chnl=0
+char id=86    x=231  y=18   width=8    height=10   xoffset=-1   yoffset=5    xadvance=8    page=0    chnl=0
+char id=87    x=241  y=18   width=12   height=10   xoffset=-1   yoffset=5    xadvance=12   page=0    chnl=0
+char id=88    x=260  y=18   width=8    height=10   xoffset=-1   yoffset=5    xadvance=8    page=0    chnl=0
+char id=89    x=270  y=18   width=9    height=10   xoffset=-2   yoffset=5    xadvance=7    page=0    chnl=0
+char id=90    x=281  y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=91    x=282  y=2    width=3    height=12   xoffset=0    yoffset=5    xadvance=4    page=0    chnl=0
+char id=92    x=462  y=2    width=6    height=11   xoffset=-1   yoffset=5    xadvance=6    page=0    chnl=0
+char id=93    x=287  y=2    width=3    height=12   xoffset=-1   yoffset=5    xadvance=4    page=0    chnl=0
+char id=94    x=360  y=30   width=7    height=5    xoffset=-1   yoffset=6    xadvance=8    page=0    chnl=0
+char id=95    x=481  y=30   width=7    height=1    xoffset=0    yoffset=16   xadvance=9    page=0    chnl=0
+char id=96    x=423  y=30   width=4    height=3    xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=97    x=198  y=30   width=6    height=7    xoffset=0    yoffset=8    xadvance=7    page=0    chnl=0
+char id=98    x=296  y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=99    x=222  y=30   width=5    height=7    xoffset=0    yoffset=8    xadvance=6    page=0    chnl=0
+char id=100   x=304  y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=101   x=229  y=30   width=6    height=7    xoffset=0    yoffset=8    xadvance=8    page=0    chnl=0
+char id=102   x=312  y=18   width=5    height=10   xoffset=-1   yoffset=5    xadvance=4    page=0    chnl=0
+char id=103   x=319  y=18   width=7    height=10   xoffset=0    yoffset=8    xadvance=7    page=0    chnl=0
+char id=104   x=328  y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=105   x=336  y=18   width=1    height=10   xoffset=0    yoffset=5    xadvance=3    page=0    chnl=0
+char id=106   x=120  y=2    width=3    height=13   xoffset=-2   yoffset=5    xadvance=3    page=0    chnl=0
+char id=107   x=349  y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=108   x=357  y=18   width=1    height=10   xoffset=0    yoffset=5    xadvance=3    page=0    chnl=0
+char id=109   x=237  y=30   width=9    height=7    xoffset=0    yoffset=8    xadvance=11   page=0    chnl=0
+char id=110   x=248  y=30   width=6    height=7    xoffset=0    yoffset=8    xadvance=8    page=0    chnl=0
+char id=111   x=256  y=30   width=6    height=7    xoffset=0    yoffset=8    xadvance=8    page=0    chnl=0
+char id=112   x=360  y=18   width=6    height=10   xoffset=0    yoffset=8    xadvance=8    page=0    chnl=0
+char id=113   x=368  y=18   width=6    height=10   xoffset=0    yoffset=8    xadvance=8    page=0    chnl=0
+char id=114   x=158  y=30   width=4    height=8    xoffset=0    yoffset=7    xadvance=5    page=0    chnl=0
+char id=115   x=264  y=30   width=5    height=7    xoffset=0    yoffset=8    xadvance=7    page=0    chnl=0
+char id=116   x=34   y=30   width=5    height=9    xoffset=-1   yoffset=6    xadvance=5    page=0    chnl=0
+char id=117   x=271  y=30   width=5    height=7    xoffset=0    yoffset=8    xadvance=7    page=0    chnl=0
+char id=118   x=278  y=30   width=7    height=7    xoffset=-1   yoffset=8    xadvance=7    page=0    chnl=0
+char id=119   x=287  y=30   width=11   height=7    xoffset=-1   yoffset=8    xadvance=11   page=0    chnl=0
+char id=120   x=300  y=30   width=6    height=7    xoffset=-1   yoffset=8    xadvance=6    page=0    chnl=0
+char id=121   x=376  y=18   width=7    height=10   xoffset=-1   yoffset=8    xadvance=7    page=0    chnl=0
+char id=122   x=308  y=30   width=5    height=7    xoffset=0    yoffset=8    xadvance=7    page=0    chnl=0
+char id=123   x=292  y=2    width=5    height=12   xoffset=-1   yoffset=5    xadvance=5    page=0    chnl=0
+char id=124   x=125  y=2    width=1    height=13   xoffset=0    yoffset=5    xadvance=3    page=0    chnl=0
+char id=125   x=299  y=2    width=5    height=12   xoffset=-1   yoffset=5    xadvance=5    page=0    chnl=0
+char id=126   x=469  y=30   width=7    height=2    xoffset=-1   yoffset=10   xadvance=8    page=0    chnl=0
+char id=160   x=0    y=0    width=0    height=0    xoffset=-1   yoffset=15   xadvance=3    page=0    chnl=0
+char id=161   x=31   y=30   width=1    height=9    xoffset=0    yoffset=8    xadvance=3    page=0    chnl=0
+char id=162   x=289  y=18   width=5    height=10   xoffset=0    yoffset=7    xadvance=7    page=0    chnl=0
+char id=163   x=22   y=30   width=7    height=9    xoffset=-1   yoffset=6    xadvance=8    page=0    chnl=0
+char id=164   x=189  y=30   width=7    height=7    xoffset=-1   yoffset=8    xadvance=7    page=0    chnl=0
+char id=165   x=11   y=30   width=9    height=9    xoffset=-2   yoffset=6    xadvance=7    page=0    chnl=0
+char id=166   x=150  y=2    width=1    height=13   xoffset=0    yoffset=5    xadvance=3    page=0    chnl=0
+char id=167   x=486  y=2    width=5    height=11   xoffset=0    yoffset=6    xadvance=7    page=0    chnl=0
+char id=168   x=0    y=42   width=4    height=1    xoffset=-1   yoffset=5    xadvance=4    page=0    chnl=0
+char id=169   x=148  y=30   width=8    height=8    xoffset=0    yoffset=5    xadvance=10   page=0    chnl=0
+char id=170   x=416  y=30   width=5    height=4    xoffset=0    yoffset=6    xadvance=6    page=0    chnl=0
+char id=171   x=352  y=30   width=6    height=5    xoffset=0    yoffset=9    xadvance=7    page=0    chnl=0
+char id=172   x=440  y=30   width=7    height=3    xoffset=-1   yoffset=10   xadvance=8    page=0    chnl=0
+char id=174   x=138  y=30   width=8    height=8    xoffset=0    yoffset=5    xadvance=10   page=0    chnl=0
+char id=175   x=490  y=30   width=5    height=1    xoffset=-2   yoffset=6    xadvance=3    page=0    chnl=0
+char id=176   x=410  y=30   width=4    height=4    xoffset=1    yoffset=5    xadvance=8    page=0    chnl=0
+char id=177   x=324  y=30   width=7    height=6    xoffset=-1   yoffset=8    xadvance=7    page=0    chnl=0
+char id=178   x=405  y=30   width=3    height=4    xoffset=-1   yoffset=4    xadvance=4    page=0    chnl=0
+char id=179   x=399  y=30   width=4    height=4    xoffset=-1   yoffset=4    xadvance=4    page=0    chnl=0
+char id=180   x=429  y=30   width=4    height=3    xoffset=-1   yoffset=4    xadvance=4    page=0    chnl=0
+char id=181   x=121  y=18   width=5    height=10   xoffset=0    yoffset=8    xadvance=7    page=0    chnl=0
+char id=182   x=110  y=18   width=9    height=10   xoffset=-1   yoffset=5    xadvance=9    page=0    chnl=0
+char id=183   x=478  y=30   width=1    height=2    xoffset=0    yoffset=10   xadvance=3    page=0    chnl=0
+char id=184   x=394  y=30   width=3    height=4    xoffset=-1   yoffset=14   xadvance=4    page=0    chnl=0
+char id=185   x=389  y=30   width=3    height=4    xoffset=-1   yoffset=4    xadvance=4    page=0    chnl=0
+char id=186   x=383  y=30   width=4    height=4    xoffset=0    yoffset=6    xadvance=6    page=0    chnl=0
+char id=187   x=344  y=30   width=6    height=5    xoffset=0    yoffset=9    xadvance=7    page=0    chnl=0
+char id=188   x=315  y=2    width=8    height=12   xoffset=-1   yoffset=4    xadvance=8    page=0    chnl=0
+char id=189   x=325  y=2    width=7    height=12   xoffset=-1   yoffset=5    xadvance=8    page=0    chnl=0
+char id=190   x=153  y=2    width=8    height=13   xoffset=-1   yoffset=3    xadvance=8    page=0    chnl=0
+char id=191   x=36   y=18   width=6    height=10   xoffset=-1   yoffset=8    xadvance=6    page=0    chnl=0
+char id=192   x=4    y=2    width=8    height=14   xoffset=-1   yoffset=1    xadvance=8    page=0    chnl=0
+char id=193   x=14   y=2    width=8    height=14   xoffset=-1   yoffset=1    xadvance=8    page=0    chnl=0
+char id=194   x=173  y=2    width=8    height=13   xoffset=-1   yoffset=2    xadvance=8    page=0    chnl=0
+char id=195   x=183  y=2    width=8    height=13   xoffset=-1   yoffset=2    xadvance=8    page=0    chnl=0
+char id=196   x=334  y=2    width=8    height=12   xoffset=-1   yoffset=3    xadvance=8    page=0    chnl=0
+char id=197   x=344  y=2    width=9    height=12   xoffset=-1   yoffset=3    xadvance=9    page=0    chnl=0
+char id=198   x=482  y=18   width=12   height=10   xoffset=-1   yoffset=5    xadvance=13   page=0    chnl=0
+char id=199   x=193  y=2    width=6    height=13   xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=200   x=24   y=2    width=6    height=14   xoffset=0    yoffset=1    xadvance=8    page=0    chnl=0
+char id=201   x=32   y=2    width=6    height=14   xoffset=0    yoffset=1    xadvance=8    page=0    chnl=0
+char id=202   x=209  y=2    width=6    height=13   xoffset=0    yoffset=2    xadvance=8    page=0    chnl=0
+char id=203   x=355  y=2    width=7    height=12   xoffset=0    yoffset=3    xadvance=8    page=0    chnl=0
+char id=204   x=49   y=2    width=4    height=14   xoffset=-2   yoffset=1    xadvance=3    page=0    chnl=0
+char id=205   x=55   y=2    width=4    height=14   xoffset=-1   yoffset=1    xadvance=3    page=0    chnl=0
+char id=206   x=217  y=2    width=5    height=13   xoffset=-2   yoffset=2    xadvance=3    page=0    chnl=0
+char id=207   x=374  y=2    width=3    height=12   xoffset=-1   yoffset=3    xadvance=3    page=0    chnl=0
+char id=208   x=339  y=18   width=8    height=10   xoffset=-1   yoffset=5    xadvance=9    page=0    chnl=0
+char id=209   x=224  y=2    width=7    height=13   xoffset=0    yoffset=2    xadvance=9    page=0    chnl=0
+char id=210   x=61   y=2    width=8    height=14   xoffset=0    yoffset=1    xadvance=10   page=0    chnl=0
+char id=211   x=71   y=2    width=8    height=14   xoffset=0    yoffset=1    xadvance=10   page=0    chnl=0
+char id=212   x=233  y=2    width=8    height=13   xoffset=0    yoffset=2    xadvance=10   page=0    chnl=0
+char id=213   x=243  y=2    width=8    height=13   xoffset=0    yoffset=2    xadvance=10   page=0    chnl=0
+char id=214   x=364  y=2    width=8    height=12   xoffset=0    yoffset=3    xadvance=10   page=0    chnl=0
+char id=215   x=181  y=30   width=6    height=7    xoffset=0    yoffset=8    xadvance=8    page=0    chnl=0
+char id=216   x=81   y=2    width=8    height=14   xoffset=0    yoffset=3    xadvance=10   page=0    chnl=0
+char id=217   x=91   y=2    width=7    height=14   xoffset=0    yoffset=1    xadvance=9    page=0    chnl=0
+char id=218   x=100  y=2    width=7    height=14   xoffset=0    yoffset=1    xadvance=9    page=0    chnl=0
+char id=219   x=253  y=2    width=7    height=13   xoffset=0    yoffset=2    xadvance=9    page=0    chnl=0
+char id=220   x=306  y=2    width=7    height=12   xoffset=0    yoffset=3    xadvance=9    page=0    chnl=0
+char id=221   x=109  y=2    width=9    height=14   xoffset=-2   yoffset=1    xadvance=7    page=0    chnl=0
+char id=222   x=426  y=18   width=7    height=10   xoffset=0    yoffset=5    xadvance=9    page=0    chnl=0
+char id=223   x=418  y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=224   x=423  y=2    width=6    height=11   xoffset=0    yoffset=4    xadvance=7    page=0    chnl=0
+char id=225   x=407  y=2    width=6    height=11   xoffset=0    yoffset=4    xadvance=7    page=0    chnl=0
+char id=226   x=187  y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=227   x=443  y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=228   x=451  y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=229   x=415  y=2    width=6    height=11   xoffset=0    yoffset=4    xadvance=7    page=0    chnl=0
+char id=230   x=169  y=30   width=10   height=7    xoffset=0    yoffset=8    xadvance=12   page=0    chnl=0
+char id=231   x=404  y=18   width=5    height=10   xoffset=0    yoffset=8    xadvance=6    page=0    chnl=0
+char id=232   x=454  y=2    width=6    height=11   xoffset=0    yoffset=4    xadvance=8    page=0    chnl=0
+char id=233   x=470  y=2    width=6    height=11   xoffset=0    yoffset=4    xadvance=8    page=0    chnl=0
+char id=234   x=474  y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=235   x=10   y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=236   x=499  y=2    width=4    height=11   xoffset=-2   yoffset=4    xadvance=3    page=0    chnl=0
+char id=237   x=493  y=2    width=4    height=11   xoffset=-1   yoffset=4    xadvance=3    page=0    chnl=0
+char id=238   x=44   y=18   width=5    height=10   xoffset=-2   yoffset=5    xadvance=3    page=0    chnl=0
+char id=239   x=255  y=18   width=3    height=10   xoffset=-1   yoffset=5    xadvance=3    page=0    chnl=0
+char id=240   x=478  y=2    width=6    height=11   xoffset=0    yoffset=4    xadvance=8    page=0    chnl=0
+char id=241   x=466  y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=242   x=438  y=2    width=6    height=11   xoffset=0    yoffset=4    xadvance=8    page=0    chnl=0
+char id=243   x=399  y=2    width=6    height=11   xoffset=0    yoffset=4    xadvance=8    page=0    chnl=0
+char id=244   x=435  y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=245   x=59   y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=246   x=51   y=18   width=6    height=10   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=247   x=336  y=30   width=6    height=5    xoffset=0    yoffset=9    xadvance=8    page=0    chnl=0
+char id=248   x=384  y=2    width=6    height=11   xoffset=0    yoffset=6    xadvance=8    page=0    chnl=0
+char id=249   x=392  y=2    width=5    height=11   xoffset=0    yoffset=4    xadvance=7    page=0    chnl=0
+char id=250   x=431  y=2    width=5    height=11   xoffset=0    yoffset=4    xadvance=7    page=0    chnl=0
+char id=251   x=411  y=18   width=5    height=10   xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=252   x=459  y=18   width=5    height=10   xoffset=0    yoffset=5    xadvance=7    page=0    chnl=0
+char id=253   x=40   y=2    width=7    height=14   xoffset=-1   yoffset=4    xadvance=7    page=0    chnl=0
+char id=254   x=201  y=2    width=6    height=13   xoffset=0    yoffset=5    xadvance=8    page=0    chnl=0
+char id=255   x=163  y=2    width=8    height=13   xoffset=-2   yoffset=5    xadvance=7    page=0    chnl=0
+char id=8226  x=377  y=30   width=4    height=4    xoffset=1    yoffset=10   xadvance=8    page=0    chnl=0
+char id=8364  x=129  y=30   width=7    height=9    xoffset=-1   yoffset=6    xadvance=8    page=0    chnl=0
+kernings count=0

+ 380 - 0
assets/ui/uiskin.atlas

@@ -0,0 +1,380 @@
+
+uiskin.png
+size: 512,512
+format: RGBA8888
+filter: Nearest,Nearest
+repeat: none
+button-normal
+  rotate: false
+  xy: 2, 111
+  size: 41, 42
+  orig: 41, 42
+  offset: 0, 0
+  index: -1
+button-normal-over
+  rotate: false
+  xy: 102, 263
+  size: 41, 42
+  orig: 41, 42
+  offset: 0, 0
+  index: -1
+button-normal-pressed
+  rotate: false
+  xy: 2, 67
+  size: 41, 42
+  orig: 41, 42
+  offset: 0, 0
+  index: -1
+check
+  rotate: false
+  xy: 290, 306
+  size: 24, 24
+  orig: 24, 24
+  offset: 0, 0
+  index: -1
+check-on
+  rotate: false
+  xy: 316, 306
+  size: 24, 24
+  orig: 24, 24
+  offset: 0, 0
+  index: -1
+checkbox
+  rotate: false
+  xy: 482, 309
+  size: 20, 21
+  orig: 20, 21
+  offset: 0, 0
+  index: -1
+checkbox-over
+  rotate: false
+  xy: 438, 309
+  size: 20, 21
+  orig: 20, 21
+  offset: 0, 0
+  index: -1
+checkbox-selected
+  rotate: false
+  xy: 32, 18
+  size: 20, 21
+  orig: 20, 21
+  offset: 0, 0
+  index: -1
+checkbox-selected-over
+  rotate: false
+  xy: 460, 309
+  size: 20, 21
+  orig: 20, 21
+  offset: 0, 0
+  index: -1
+font
+  rotate: false
+  xy: 2, 402
+  size: 504, 44
+  orig: 504, 44
+  offset: 0, 0
+  index: -1
+font-list
+  rotate: false
+  xy: 2, 332
+  size: 505, 30
+  orig: 505, 30
+  offset: 0, 0
+  index: -1
+font-subtitle
+  rotate: false
+  xy: 2, 364
+  size: 505, 36
+  orig: 505, 36
+  offset: 0, 0
+  index: -1
+font-window
+  rotate: false
+  xy: 2, 448
+  size: 506, 62
+  orig: 506, 62
+  offset: 0, 0
+  index: -1
+knob-h
+  rotate: false
+  xy: 188, 268
+  size: 24, 1
+  orig: 24, 1
+  offset: 0, 0
+  index: -1
+knob-v
+  rotate: false
+  xy: 508, 422
+  size: 1, 24
+  orig: 1, 24
+  offset: 0, 0
+  index: -1
+line-h
+  rotate: false
+  xy: 102, 260
+  size: 24, 1
+  orig: 24, 1
+  offset: 0, 0
+  index: -1
+line-v
+  rotate: false
+  xy: 509, 396
+  size: 1, 24
+  orig: 1, 24
+  offset: 0, 0
+  index: -1
+list
+  rotate: false
+  xy: 188, 271
+  size: 43, 34
+  orig: 43, 34
+  offset: 0, 0
+  index: -1
+progress-bar
+  rotate: false
+  xy: 2, 307
+  size: 252, 5
+  orig: 252, 5
+  offset: 0, 0
+  index: -1
+progress-bar-knob
+  rotate: false
+  xy: 2, 314
+  size: 252, 5
+  orig: 252, 5
+  offset: 0, 0
+  index: -1
+progress-bar-square
+  rotate: false
+  xy: 256, 309
+  size: 4, 4
+  orig: 4, 4
+  offset: 0, 0
+  index: -1
+progress-bar-square-knob
+  rotate: false
+  xy: 504, 328
+  size: 2, 2
+  orig: 2, 2
+  offset: 0, 0
+  index: -1
+radio
+  rotate: false
+  xy: 366, 308
+  size: 22, 22
+  orig: 22, 22
+  offset: 0, 0
+  index: -1
+radio-over
+  rotate: false
+  xy: 390, 308
+  size: 22, 22
+  orig: 22, 22
+  offset: 0, 0
+  index: -1
+radio-selected
+  rotate: false
+  xy: 342, 308
+  size: 22, 22
+  orig: 22, 22
+  offset: 0, 0
+  index: -1
+radio-selected-over
+  rotate: false
+  xy: 414, 308
+  size: 22, 22
+  orig: 22, 22
+  offset: 0, 0
+  index: -1
+rect
+  rotate: false
+  xy: 32, 41
+  size: 12, 24
+  orig: 12, 24
+  offset: 0, 0
+  index: -1
+scrollbar
+  rotate: false
+  xy: 46, 150
+  size: 17, 16
+  orig: 17, 16
+  offset: 0, 0
+  index: -1
+select
+  rotate: false
+  xy: 262, 306
+  size: 26, 24
+  split: 4, 15, 0, 24
+  orig: 26, 24
+  offset: 0, 0
+  index: -1
+select-box
+  rotate: false
+  xy: 145, 263
+  size: 41, 42
+  orig: 41, 42
+  offset: 0, 0
+  index: -1
+select-box-open
+  rotate: false
+  xy: 58, 214
+  size: 41, 42
+  orig: 41, 42
+  offset: 0, 0
+  index: -1
+selection
+  rotate: false
+  xy: 46, 168
+  size: 16, 16
+  orig: 16, 16
+  offset: 0, 0
+  index: -1
+slider
+  rotate: false
+  xy: 2, 321
+  size: 258, 9
+  orig: 258, 9
+  offset: 0, 0
+  index: -1
+slider-knob
+  rotate: false
+  xy: 46, 57
+  size: 9, 9
+  orig: 9, 9
+  offset: 0, 0
+  index: -1
+slider-knob-over
+  rotate: false
+  xy: 46, 46
+  size: 9, 9
+  orig: 9, 9
+  offset: 0, 0
+  index: -1
+spinner-down
+  rotate: false
+  xy: 45, 100
+  size: 16, 14
+  orig: 16, 14
+  offset: 0, 0
+  index: -1
+spinner-down-over
+  rotate: false
+  xy: 45, 68
+  size: 16, 14
+  orig: 16, 14
+  offset: 0, 0
+  index: -1
+spinner-down-pressed
+  rotate: false
+  xy: 45, 116
+  size: 16, 14
+  orig: 16, 14
+  offset: 0, 0
+  index: -1
+spinner-textfield
+  rotate: false
+  xy: 2, 7
+  size: 28, 28
+  orig: 28, 28
+  offset: 0, 0
+  index: -1
+spinner-textfield-selected
+  rotate: false
+  xy: 2, 37
+  size: 28, 28
+  orig: 28, 28
+  offset: 0, 0
+  index: -1
+spinner-up
+  rotate: false
+  xy: 32, 2
+  size: 16, 14
+  orig: 16, 14
+  offset: 0, 0
+  index: -1
+spinner-up-over
+  rotate: false
+  xy: 45, 84
+  size: 16, 14
+  orig: 16, 14
+  offset: 0, 0
+  index: -1
+spinner-up-pressed
+  rotate: false
+  xy: 50, 2
+  size: 16, 14
+  orig: 16, 14
+  offset: 0, 0
+  index: -1
+square
+  rotate: false
+  xy: 256, 315
+  size: 4, 4
+  orig: 4, 4
+  offset: 0, 0
+  index: -1
+textfield
+  rotate: false
+  xy: 2, 155
+  size: 42, 47
+  orig: 42, 47
+  offset: 0, 0
+  index: -1
+textfield-selected
+  rotate: false
+  xy: 58, 258
+  size: 42, 47
+  orig: 42, 47
+  offset: 0, 0
+  index: -1
+tree-minus
+  rotate: false
+  xy: 46, 186
+  size: 16, 16
+  orig: 16, 16
+  offset: 0, 0
+  index: -1
+tree-plus
+  rotate: false
+  xy: 45, 132
+  size: 16, 16
+  orig: 16, 16
+  offset: 0, 0
+  index: -1
+white
+  rotate: false
+  xy: 509, 393
+  size: 1, 1
+  orig: 1, 1
+  offset: 0, 0
+  index: -1
+dot
+  rotate: false
+  xy: 509, 393
+  size: 1, 1
+  orig: 1, 1
+  offset: 0, 0
+  index: -1
+window
+  rotate: false
+  xy: 2, 204
+  size: 54, 101
+  orig: 54, 101
+  offset: 0, 0
+  index: -1
+window-border
+  rotate: false
+  xy: 248, 279
+  size: 5, 26
+  split: 2, 2, 23, 2
+  orig: 5, 26
+  offset: 0, 0
+  index: -1
+window-resize
+  rotate: false
+  xy: 233, 271
+  size: 13, 34
+  split: 2, 10, 23, 10
+  orig: 13, 34
+  offset: 0, 0
+  index: -1

+ 68 - 0
build.gradle

@@ -0,0 +1,68 @@
+buildscript {
+  repositories {
+    mavenCentral()
+    gradlePluginPortal()
+    mavenLocal()
+    google()
+    maven { url = 'https://central.sonatype.com/repository/maven-snapshots/' }
+  }
+  dependencies {
+
+  }
+}
+
+allprojects {
+  apply plugin: 'eclipse'
+  apply plugin: 'idea'
+
+  // This allows you to "Build and run using IntelliJ IDEA", an option in IDEA's Settings.
+  idea {
+    module {
+      outputDir = file('build/classes/java/main')
+      testOutputDir = file('build/classes/java/test')
+    }
+  }
+}
+
+configure(subprojects) {
+  apply plugin: 'java-library'
+  java.sourceCompatibility = 21
+
+  // From https://lyze.dev/2021/04/29/libGDX-Internal-Assets-List/
+  // The article can be helpful when using assets.txt in your project.
+  tasks.register('generateAssetList') {
+    inputs.dir("${project.rootDir}/assets/")
+    // projectFolder/assets
+    File assetsFolder = new File("${project.rootDir}/assets/")
+    // projectFolder/assets/assets.txt
+    File assetsFile = new File(assetsFolder, "assets.txt")
+    // delete that file in case we've already created it
+    assetsFile.delete()
+
+    // iterate through all files inside that folder
+    // convert it to a relative path
+    // and append it to the file assets.txt
+    fileTree(assetsFolder).collect { assetsFolder.relativePath(it) }.sort().each {
+      assetsFile.append(it + "\n")
+    }
+  }
+  processResources.dependsOn 'generateAssetList'
+
+  compileJava {
+    options.incremental = true
+  }
+}
+
+subprojects {
+  version = "$projectVersion"
+  ext.appName = 'Smog'
+  repositories {
+    mavenCentral()
+    // You may want to remove the following line if you have errors downloading dependencies.
+    mavenLocal()
+    maven { url = 'https://central.sonatype.com/repository/maven-snapshots/' }
+    maven { url = 'https://jitpack.io' }
+  }
+}
+
+eclipse.project.name = 'Smog' + '-parent'

+ 20 - 0
core/build.gradle

@@ -0,0 +1,20 @@
+[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
+eclipse.project.name = appName + '-core'
+
+dependencies {
+  implementation "com.esotericsoftware:kryonet:2.22.0-RC1"
+  api "com.badlogicgames.ashley:ashley:$ashleyVersion"
+  api "com.badlogicgames.box2dlights:box2dlights:$box2dlightsVersion"
+  api "com.badlogicgames.gdx:gdx-ai:$aiVersion"
+  api "com.badlogicgames.gdx:gdx-box2d:$gdxVersion"
+  api "com.badlogicgames.gdx:gdx:$gdxVersion"
+  api project(':shared')
+
+  if(enableGraalNative == 'true') {
+    implementation "io.github.berstanio:gdx-svmhelper-annotations:$graalHelperVersion"
+  }
+}
+
+jar {
+  duplicatesStrategy = DuplicatesStrategy.EXCLUDE
+}

+ 15 - 0
core/src/main/java/me/lethunderhawk/Main.java

@@ -0,0 +1,15 @@
+package me.lethunderhawk;
+
+import com.badlogic.gdx.ApplicationListener;
+import com.badlogic.gdx.Game;
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.InputAdapter;
+import me.lethunderhawk.screen.MenuScreen;
+
+/** {@link com.badlogic.gdx.ApplicationListener} implementation shared by all platforms. Listens to user input. */
+public class Main extends Game {
+    @Override
+    public void create() {
+        setScreen(new MenuScreen(this));
+    }
+}

+ 14 - 0
core/src/main/java/me/lethunderhawk/entity/Player.java

@@ -0,0 +1,14 @@
+package me.lethunderhawk.entity;
+
+import java.util.UUID;
+
+public class Player {
+    public UUID uuid;
+    public float x;
+    public float y;
+
+    public Player(){
+        this.uuid = UUID.randomUUID();
+    }
+
+}

+ 75 - 0
core/src/main/java/me/lethunderhawk/network/GameClient.java

@@ -0,0 +1,75 @@
+package me.lethunderhawk.network;
+
+import com.esotericsoftware.kryonet.Client;
+import com.esotericsoftware.kryonet.Connection;
+import com.esotericsoftware.kryonet.Listener;
+import me.lethunderhawk.entity.Player;
+
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class GameClient extends Listener {
+
+    private final Client client;
+    private final Map<UUID, Player> otherPlayers = new ConcurrentHashMap<>();
+    private final Player player;
+
+    public GameClient() {
+        this.player = new Player();
+        client = new Client();
+
+        client.start();
+
+        registerPackets();
+    }
+
+    private void registerPackets() {
+        NetworkRegister.register(client.getKryo());
+    }
+
+    public void connect(String ip) throws IOException {
+
+        client.connect(
+            5000,
+            ip,
+            54555,
+            54777
+        );
+        client.addListener(this);
+    }
+
+    public void send(Object packet) {
+
+        client.sendUDP(packet);
+    }
+
+    @Override
+    public void received (Connection connection, Object object) {
+        if(object instanceof Packets.PlayerLoginPacket packet) {
+            otherPlayers.put(packet.player.uuid, packet.player);
+        }
+
+        if(object instanceof Packets.PlayerPositionPacket packet) {
+            handlePlayerPosition(packet);
+        }
+    }
+
+    private void handlePlayerPosition(Packets.PlayerPositionPacket packet) {
+        Player player = otherPlayers.computeIfAbsent(packet.player.uuid, uuid -> {
+            Player p = new Player();
+            p.uuid = uuid;
+            return p;
+        });
+        player.x = packet.x;
+        player.y = packet.y;
+    }
+
+    public Player getPlayer() {
+        return player;
+    }
+
+    public Map<UUID, Player> getOtherPlayers() {
+        return otherPlayers;
+    }
+}

+ 29 - 0
core/src/main/java/me/lethunderhawk/network/NetworkRegister.java

@@ -0,0 +1,29 @@
+package me.lethunderhawk.network;
+
+import com.esotericsoftware.kryo.Kryo;
+import com.esotericsoftware.kryo.Serializer;
+import com.esotericsoftware.kryo.io.Input;
+import com.esotericsoftware.kryo.io.Output;
+import com.esotericsoftware.kryo.serializers.DefaultSerializers;
+import me.lethunderhawk.entity.Player;
+
+import java.util.UUID;
+
+public class NetworkRegister {
+
+    public static void register(Kryo kryo) {
+        kryo.register(Packets.PlayerPositionPacket.class);
+        kryo.register(Packets.PlayerLoginPacket.class);
+        kryo.register(Player.class);
+        kryo.register(UUID.class, new Serializer<UUID>() {
+            public void write(Kryo kryo, Output out, UUID uuid) {
+                out.writeLong(uuid.getMostSignificantBits());
+                out.writeLong(uuid.getLeastSignificantBits());
+            }
+
+            public UUID read(Kryo kryo, Input in, Class<UUID> type) {
+                return new UUID(in.readLong(), in.readLong());
+            }
+        });
+    }
+}

+ 32 - 0
core/src/main/java/me/lethunderhawk/network/Packets.java

@@ -0,0 +1,32 @@
+package me.lethunderhawk.network;
+
+import me.lethunderhawk.entity.Player;
+
+import java.awt.*;
+
+public class Packets {
+
+    /*public abstract static class Packet{
+        abstract void onReceive();
+
+    }*/
+
+    public static class PlayerPositionPacket {
+        public Player player;
+        public float x;
+        public float y;
+
+        public PlayerPositionPacket() {}
+
+        public PlayerPositionPacket(Player player, float x, float y) {
+            this.player = player;
+            this.x = x;
+            this.y = y;
+        }
+    }
+
+    public static class PlayerLoginPacket {
+        public Player player;
+
+    }
+}

+ 105 - 0
core/src/main/java/me/lethunderhawk/screen/GameScreen.java

@@ -0,0 +1,105 @@
+package me.lethunderhawk.screen;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.Input;
+import com.badlogic.gdx.Screen;
+import com.badlogic.gdx.graphics.GL20;
+import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
+import me.lethunderhawk.Main;
+import me.lethunderhawk.entity.Player;
+import me.lethunderhawk.network.GameClient;
+import me.lethunderhawk.network.Packets;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+public class GameScreen implements Screen {
+
+    private final ShapeRenderer shapeRenderer;
+    private final GameClient client;
+
+    public GameScreen(Main game, String ip) {
+
+        shapeRenderer = new ShapeRenderer();
+
+        client = new GameClient();
+
+        try {
+            client.connect(ip);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void render(float delta) {
+
+        update(delta);
+
+        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
+
+        shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
+        Player player = client.getPlayer();
+        shapeRenderer.rect(player.x, player.y, 50, 50);
+
+        for(Map.Entry<UUID, Player> entry : client.getOtherPlayers().entrySet()) {
+            Player otherPlayer = entry.getValue();
+            shapeRenderer.rect(otherPlayer.x, otherPlayer.y, 50, 50);
+        }
+
+        shapeRenderer.end();
+    }
+
+    private void update(float delta) {
+
+        float speed = 300f;
+
+        boolean moved = false;
+        Player currentPlayer = client.getPlayer();
+
+        if(Gdx.input.isKeyPressed(Input.Keys.W)) {
+            currentPlayer.y += speed * delta;
+            moved = true;
+        }
+
+        if(Gdx.input.isKeyPressed(Input.Keys.S)) {
+            currentPlayer.y -= speed * delta;
+            moved = true;
+        }
+
+        if(Gdx.input.isKeyPressed(Input.Keys.A)) {
+            currentPlayer.x -= speed * delta;
+            moved = true;
+        }
+
+        if(Gdx.input.isKeyPressed(Input.Keys.D)) {
+            currentPlayer.x += speed * delta;
+            moved = true;
+        }
+
+        if(moved) {
+
+            Packets.PlayerPositionPacket packet =
+                new Packets.PlayerPositionPacket(currentPlayer, currentPlayer.x, currentPlayer.y);
+
+            client.send(packet);
+        }
+    }
+
+
+    @Override
+    public void show() {}
+    @Override
+    public void resize(int width, int height) {}
+    @Override
+    public void pause() {}
+    @Override
+    public void resume() {}
+    @Override
+    public void hide() {}
+    @Override
+    public void dispose() {}
+}

+ 117 - 0
core/src/main/java/me/lethunderhawk/screen/MenuScreen.java

@@ -0,0 +1,117 @@
+package me.lethunderhawk.screen;
+
+import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.Screen;
+import com.badlogic.gdx.assets.AssetManager;
+import com.badlogic.gdx.graphics.GL20;
+import com.badlogic.gdx.scenes.scene2d.Stage;
+import com.badlogic.gdx.scenes.scene2d.ui.Label;
+import com.badlogic.gdx.scenes.scene2d.ui.Skin;
+import com.badlogic.gdx.scenes.scene2d.ui.Table;
+import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
+import com.badlogic.gdx.scenes.scene2d.ui.TextField;
+import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
+import com.badlogic.gdx.utils.viewport.ScreenViewport;
+import com.badlogic.gdx.InputMultiplexer;
+import com.badlogic.gdx.scenes.scene2d.InputEvent;
+import me.lethunderhawk.Main;
+
+public class MenuScreen implements Screen {
+
+    private final Main game;
+    private Stage stage;
+    private Skin skin;
+    private TextField ipField;
+    private final AssetManager assets;
+
+    public MenuScreen(Main game) {
+        this.game = game;
+        this.assets = new AssetManager();
+    }
+
+    @Override
+    public void show() {
+        // Setup stage and viewport
+        stage = new Stage(new ScreenViewport());
+
+        // Load skin via AssetManager (skin file path relative to assets/)
+        // Ensure ui/uiskin.json references the atlas/image with correct relative paths.
+        try {
+            assets.load("ui/uiskin.json", Skin.class);
+            assets.finishLoading(); // blocking load; change if async desired
+            skin = assets.get("ui/uiskin.json", Skin.class);
+        } catch (Exception e) {
+            Gdx.app.error("MenuScreen", "Failed to load skin: ui/uiskin.json", e);
+            // Fallback: create an empty skin so UI code doesn't NPE (will look ugly)
+            skin = new Skin();
+        }
+
+        // Build UI table
+        Table table = new Table();
+        table.setFillParent(true);
+        table.center();
+        stage.addActor(table);
+
+        // Label
+        Label label = new Label("Enter Server IP:", skin);
+
+        // IP Input Field (use style from skin)
+        ipField = new TextField("localhost", skin);
+
+        // Start Button
+        TextButton startButton = new TextButton("Start Game", skin);
+        startButton.addListener(new ClickListener() {
+            @Override
+            public void clicked(InputEvent event, float x, float y) {
+                String ip = ipField.getText();
+                if (ip == null || ip.trim().isEmpty()) {
+                    ip = "localhost";
+                }
+                game.setScreen(new GameScreen(game, ip));
+            }
+        });
+
+        // Layout components
+        table.add(label).padBottom(10).row();
+        table.add(ipField).width(300).padBottom(20).row();
+        table.add(startButton).width(200);
+
+        // Set input processor
+        Gdx.input.setInputProcessor(stage);
+    }
+
+    @Override
+    public void render(float delta) {
+        Gdx.gl.glClearColor(0.12f, 0.12f, 0.12f, 1f); // dark background
+        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
+
+        stage.act(Math.min(delta, 1/30f));
+        stage.draw();
+    }
+
+    @Override
+    public void resize(int width, int height) {
+        if (stage != null) {
+            stage.getViewport().update(width, height, true);
+        }
+    }
+
+    @Override
+    public void pause() {}
+    @Override
+    public void resume() {}
+    @Override
+    public void hide() {
+        // clear input when hidden
+        if (Gdx.input.getInputProcessor() == stage) {
+            Gdx.input.setInputProcessor(null);
+        }
+    }
+
+    @Override
+    public void dispose() {
+        if (stage != null) stage.dispose();
+        if (skin != null) skin.dispose();
+        if (assets != null) assets.dispose();
+    }
+}

+ 23 - 0
gradle.properties

@@ -0,0 +1,23 @@
+# This doesn't need to be false, and some projects may be able to take advantage of setting daemon to true.
+# We set it to false by default in order to avoid too many daemons from being created and persisting; each needs RAM.
+org.gradle.daemon=false
+# Sets starting memory usage to 512MB, maximum memory usage to 1GB, and tries to set as much to use Unicode as we can.
+org.gradle.jvmargs=-Xms512M -Xmx1G -Dfile.encoding=UTF-8 -Dconsole.encoding=UTF-8
+# "Configure on-demand" must be false because it breaks projects that have Android modules. The default is also false.
+org.gradle.configureondemand=false
+# The logging level determines which messages get shown about how Gradle itself is working, such as if build.gradle
+# files are fully future-proof (which they never are, because Gradle constantly deprecates working APIs).
+# You can change 'quiet' below to 'lifecycle' to use Gradle's default behavior, which shows some confusing messages.
+# You could instead change 'quiet' below to 'info' to see info that's important mainly while debugging build files.
+# Note that if you want to use Gradle Build Scans, you should set the below logging level to 'lifecycle', otherwise
+# the link to the scan won't get shown at all.
+# Documented at: https://docs.gradle.org/current/userguide/command_line_interface.html#sec:command_line_logging
+org.gradle.logging.level=quiet
+aiVersion=1.8.2
+ashleyVersion=1.7.4
+box2dlightsVersion=1.5
+lwjgl3Version=3.4.1
+graalHelperVersion=2.0.1
+enableGraalNative=false
+gdxVersion=1.14.0
+projectVersion=1.0.0

+ 248 - 0
gradlew

@@ -0,0 +1,248 @@
+#!/bin/sh
+
+#
+# Copyright © 2015 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+#
+
+##############################################################################
+#
+#   Gradle start up script for POSIX generated by Gradle.
+#
+#   Important for running:
+#
+#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+#       noncompliant, but you have some other compliant shell such as ksh or
+#       bash, then to run this script, type that shell name before the whole
+#       command line, like:
+#
+#           ksh Gradle
+#
+#       Busybox and similar reduced shells will NOT work, because this script
+#       requires all of these POSIX shell features:
+#         * functions;
+#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+#         * compound commands having a testable exit status, especially «case»;
+#         * various built-in commands including «command», «set», and «ulimit».
+#
+#   Important for patching:
+#
+#   (2) This script targets any POSIX shell, so it avoids extensions provided
+#       by Bash, Ksh, etc; in particular arrays are avoided.
+#
+#       The "traditional" practice of packing multiple parameters into a
+#       space-separated string is a well documented source of bugs and security
+#       problems, so this is (mostly) avoided, by progressively accumulating
+#       options in "$@", and eventually passing that to Java.
+#
+#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+#       see the in-line comments for details.
+#
+#       There are tweaks for specific operating systems such as AIX, CygWin,
+#       Darwin, MinGW, and NonStop.
+#
+#   (3) This script is generated from the Groovy template
+#       https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+#       within the Gradle project.
+#
+#       You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
+    [ -h "$app_path" ]
+do
+    ls=$( ls -ld "$app_path" )
+    link=${ls#*' -> '}
+    case $link in             #(
+      /*)   app_path=$link ;; #(
+      *)    app_path=$APP_HOME$link ;;
+    esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+    echo "$*"
+} >&2
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in                #(
+  CYGWIN* )         cygwin=true  ;; #(
+  Darwin* )         darwin=true  ;; #(
+  MSYS* | MINGW* )  msys=true    ;; #(
+  NONSTOP* )        nonstop=true ;;
+esac
+
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD=$JAVA_HOME/jre/sh/java
+    else
+        JAVACMD=$JAVA_HOME/bin/java
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD=java
+    if ! command -v java >/dev/null 2>&1
+    then
+        die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+    case $MAX_FD in #(
+      max*)
+        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
+        MAX_FD=$( ulimit -H -n ) ||
+            warn "Could not query maximum file descriptor limit"
+    esac
+    case $MAX_FD in  #(
+      '' | soft) :;; #(
+      *)
+        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+        # shellcheck disable=SC2039,SC3045
+        ulimit -n "$MAX_FD" ||
+            warn "Could not set maximum file descriptor limit to $MAX_FD"
+    esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+#   * args from the command line
+#   * the main class name
+#   * -classpath
+#   * -D...appname settings
+#   * --module-path (only if needed)
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+
+    JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    for arg do
+        if
+            case $arg in                                #(
+              -*)   false ;;                            # don't mess with options #(
+              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
+                    [ -e "$t" ] ;;                      #(
+              *)    false ;;
+            esac
+        then
+            arg=$( cygpath --path --ignore --mixed "$arg" )
+        fi
+        # Roll the args list around exactly as many times as the number of
+        # args, so each arg winds up back in the position where it started, but
+        # possibly modified.
+        #
+        # NB: a `for` loop captures its iteration list before it begins, so
+        # changing the positional parameters here affects neither the number of
+        # iterations, nor the values presented in `arg`.
+        shift                   # remove old arg
+        set -- "$@" "$arg"      # push replacement arg
+    done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+#     and any embedded shellness will be escaped.
+#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+#     treated as '${Hostname}' itself on the command line.
+
+set -- \
+        "-Dorg.gradle.appname=$APP_BASE_NAME" \
+        -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
+        "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+    die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+#   set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+        xargs -n1 |
+        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+        tr '\n' ' '
+    )" '"$@"'
+
+exec "$JAVACMD" "$@"

+ 82 - 0
gradlew.bat

@@ -0,0 +1,82 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem      https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+@rem SPDX-License-Identifier: Apache-2.0
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem  Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables, and ensure extensions are enabled
+setlocal EnableExtensions
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+"%COMSPEC%" /c exit 1
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+"%COMSPEC%" /c exit 1
+
+:execute
+@rem Setup the command line
+
+
+
+@rem Execute Gradle
+@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
+@rem which allows us to clear the local environment before executing the java command
+endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
+
+:exitWithErrorLevel
+@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
+"%COMSPEC%" /c exit %ERRORLEVEL%

+ 209 - 0
lwjgl3/build.gradle

@@ -0,0 +1,209 @@
+
+buildscript {
+  repositories {
+    gradlePluginPortal()
+  }
+  dependencies {
+    classpath "io.github.fourlastor:construo:2.1.0"
+    if(enableGraalNative == 'true') {
+      classpath "org.graalvm.buildtools.native:org.graalvm.buildtools.native.gradle.plugin:0.9.28"
+    }
+  }
+}
+plugins {
+  id "application"
+}
+apply plugin: 'io.github.fourlastor.construo'
+
+
+import io.github.fourlastor.construo.Target
+
+sourceSets.main.resources.srcDirs += [ rootProject.file('assets').path ]
+application.mainClass = 'me.lethunderhawk.lwjgl3.Lwjgl3Launcher'
+application.applicationName = appName
+eclipse.project.name = appName + '-lwjgl3'
+java.sourceCompatibility = 21
+java.targetCompatibility = 21
+if (JavaVersion.current().isJava9Compatible()) {
+        compileJava.options.release.set(21)
+}
+
+dependencies {
+  implementation "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion"
+  implementation "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-desktop"
+  implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
+  implementation project(':core')
+
+  if(enableGraalNative == 'true') {
+    implementation "io.github.berstanio:gdx-svmhelper-backend-lwjgl3:$graalHelperVersion"
+      implementation "io.github.berstanio:gdx-svmhelper-extension-box2d:$graalHelperVersion"
+
+  }
+  // Forces LWJGL3 to use at least $lwjgl3Version, currently 3.4.1, to avoid problems on Java 25 and up.
+  constraints{
+    implementation("org.lwjgl:lwjgl:$lwjgl3Version")
+    implementation("org.lwjgl:lwjgl-glfw:$lwjgl3Version")
+    implementation("org.lwjgl:lwjgl-jemalloc:$lwjgl3Version")
+    implementation("org.lwjgl:lwjgl-openal:$lwjgl3Version")
+    implementation("org.lwjgl:lwjgl-opengl:$lwjgl3Version")
+    implementation("org.lwjgl:lwjgl-stb:$lwjgl3Version")
+  }
+}
+
+def os = System.properties['os.name'].toLowerCase(Locale.ROOT)
+
+run {
+  workingDir = rootProject.file('assets').path
+// You can uncomment the next line if your IDE claims a build failure even when the app closed properly.
+  //setIgnoreExitValue(true)
+  jvmArgs += "--enable-native-access=ALL-UNNAMED"
+  if (os.contains('mac')) jvmArgs += "-XstartOnFirstThread"
+}
+
+jar {
+// sets the name of the .jar file this produces to the name of the game or app, with the version after.
+  archiveFileName.set("${appName}-${projectVersion}.jar")
+// the duplicatesStrategy matters starting in Gradle 7.0; this setting works.
+  duplicatesStrategy = DuplicatesStrategy.EXCLUDE
+  dependsOn configurations.runtimeClasspath
+  from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
+// these "exclude" lines remove some unnecessary duplicate files in the output JAR.
+  exclude('META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA')
+  dependencies {
+    exclude('META-INF/INDEX.LIST', 'META-INF/maven/**')
+  }
+// setting the manifest makes the JAR runnable.
+// enabling native access helps avoid a warning when Java 24 or later runs the JAR.
+// setting Multi-Release to true allows LWJGL3 to use different classes on recent Java versions.
+  manifest {
+    attributes 'Main-Class': application.mainClass, 'Enable-Native-Access': 'ALL-UNNAMED', 'Multi-Release': 'true'
+  }
+// this last step may help on some OSes that need extra instruction to make runnable JARs.
+  doLast {
+    file(archiveFile).setExecutable(true, false)
+  }
+}
+
+// Builds a JAR that only includes the files needed to run on macOS, not Windows or Linux.
+// The file size for a Mac-only JAR is about 7MB smaller than a cross-platform JAR.
+tasks.register("jarMac") {
+  dependsOn("jar")
+  group("build")
+  jar.archiveFileName.set("${appName}-${projectVersion}-mac.jar")
+  jar.exclude("windows/x86/**", "windows/x64/**", "linux/arm32/**", "linux/arm64/**", "linux/x64/**", "**/*.dll", "**/*.so",
+    'META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA')
+  dependencies {
+    jar.exclude("windows/x86/**", "windows/x64/**", "linux/arm32/**", "linux/arm64/**", "linux/x64/**",
+      'META-INF/INDEX.LIST', 'META-INF/maven/**')
+  }
+}
+
+// Builds a JAR that only includes the files needed to run on Linux, not Windows or macOS.
+// The file size for a Linux-only JAR is about 5MB smaller than a cross-platform JAR.
+tasks.register("jarLinux") {
+  dependsOn("jar")
+  group("build")
+  jar.archiveFileName.set("${appName}-${projectVersion}-linux.jar")
+  jar.exclude("windows/x86/**", "windows/x64/**", "macos/arm64/**", "macos/x64/**", "**/*.dll", "**/*.dylib",
+    'META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA')
+  dependencies {
+    jar.exclude("windows/x86/**", "windows/x64/**", "macos/arm64/**", "macos/x64/**",
+      'META-INF/INDEX.LIST', 'META-INF/maven/**')
+  }
+}
+
+// Builds a JAR that only includes the files needed to run on Windows, not Linux or macOS.
+// The file size for a Windows-only JAR is about 6MB smaller than a cross-platform JAR.
+tasks.register("jarWin") {
+  dependsOn("jar")
+  group("build")
+  jar.archiveFileName.set("${appName}-${projectVersion}-win.jar")
+  jar.exclude("macos/arm64/**", "macos/x64/**", "linux/arm32/**", "linux/arm64/**", "linux/x64/**", "**/*.dylib", "**/*.so",
+    'META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA')
+  dependencies {
+    jar.exclude("macos/arm64/**", "macos/x64/**", "linux/arm32/**", "linux/arm64/**", "linux/x64/**",
+      'META-INF/INDEX.LIST', 'META-INF/maven/**')
+  }
+}
+
+construo {
+  // name of the executable
+  name.set(appName)
+  // human-readable name, used for example in the `.app` name for macOS
+  humanName.set(appName)
+  jlink {
+    guessModulesFromJar.set(false)
+    // You may need to add more modules, as needed.
+    modules.addAll("java.base", "java.management", "java.desktop", "jdk.unsupported")
+  }
+
+  targets.configure {
+    register("linuxX64", Target.Linux) {
+      architecture.set(Target.Architecture.X86_64)
+      jdkUrl.set("https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.10%2B7/OpenJDK21U-jdk_x64_linux_hotspot_21.0.10_7.tar.gz")
+      // Linux does not currently have a way to set the icon on the executable
+    }
+    register("macM1", Target.MacOs) {
+      architecture.set(Target.Architecture.AARCH64)
+      jdkUrl.set("https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.10%2B7/OpenJDK21U-jdk_aarch64_mac_hotspot_21.0.10_7.tar.gz")
+      // macOS needs an identifier
+      identifier.set("me.lethunderhawk." + appName)
+      // Optional: icon for macOS, as an ICNS file
+      macIcon.set(project.file("icons/logo.icns"))
+    }
+    register("macX64", Target.MacOs) {
+      architecture.set(Target.Architecture.X86_64)
+      jdkUrl.set("https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.10%2B7/OpenJDK21U-jdk_x64_mac_hotspot_21.0.10_7.tar.gz")
+      // macOS needs an identifier
+      identifier.set("me.lethunderhawk." + appName)
+      // Optional: icon for macOS, as an ICNS file
+      macIcon.set(project.file("icons/logo.icns"))
+    }
+    register("winX64", Target.Windows) {
+      architecture.set(Target.Architecture.X86_64)
+      // Optional: icon for Windows, as a PNG
+      icon.set(project.file("icons/logo.png"))
+      jdkUrl.set("https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.10%2B7/OpenJDK21U-jdk_x64_windows_hotspot_21.0.10_7.zip")
+      // Uncomment the next line to show a console when the game runs, to print messages.
+      //useConsole.set(true)
+    }
+  }
+}
+
+// Equivalent to the jar task; here for compatibility with gdx-setup.
+tasks.register('dist') {
+  dependsOn 'jar'
+}
+
+distributions {
+  main {
+    contents {
+      into('libs') {
+        project.configurations.runtimeClasspath.files.findAll { file ->
+          file.getName() != project.tasks.jar.outputs.files.singleFile.name
+        }.each { file ->
+          exclude file.name
+        }
+      }
+    }
+  }
+}
+
+startScripts.dependsOn(':lwjgl3:jar')
+startScripts.classpath = project.tasks.jar.outputs.files
+
+// Helps if debugging on Linux with an Nvidia GPU.
+// This means StartupHelper won't try to restart the JVM, which can prevent debugging.
+// This only applies to Gradle tasks, not main methods debugged when launching a main() method directly.
+// As a more general solution, set the environment variable __GL_THREADED_OPTIMIZATIONS to 0 globally, on Linux
+// machines with Nvidia GPUs where you need to debug LWJGL3 apps and games.
+// You can also set __GL_THREADED_OPTIMIZATIONS to 0 in run configurations, which you would need per main() method.
+// StartupHelper will still restart the JVM to set this environment variable when run as a distributable JAR, which is
+// a good thing for end users. They won't need to ever set the debug-specific environment variable.
+tasks.withType(JavaExec.class).configureEach {
+  environment("__GL_THREADED_OPTIMIZATIONS", 0)
+}
+
+if(enableGraalNative == 'true') {
+  apply from: file("nativeimage.gradle")
+}

BIN
lwjgl3/icons/logo.icns


BIN
lwjgl3/icons/logo.ico


BIN
lwjgl3/icons/logo.png


+ 54 - 0
lwjgl3/nativeimage.gradle

@@ -0,0 +1,54 @@
+
+project(":lwjgl3") {
+  apply plugin: "org.graalvm.buildtools.native"
+
+  graalvmNative {
+    binaries {
+      main {
+        imageName = appName
+        mainClass = application.mainClass
+        requiredVersion = '23.0'
+        buildArgs.add("-march=compatibility")
+        jvmArgs.addAll("-Dfile.encoding=UTF8")
+        sharedLibrary = false
+        resources.autodetect()
+      }
+    }
+  }
+
+  run {
+    doNotTrackState("Running the app should not be affected by Graal.")
+  }
+
+  // Modified from https://lyze.dev/2021/04/29/libGDX-Internal-Assets-List/ ; thanks again, Lyze!
+  // This creates a resource-config.json file based on the contents of the assets folder (and the libGDX icons).
+  // This file is used by Graal Native to embed those specific files.
+  // This has to run before nativeCompile, so it runs at the start of an unrelated resource-handling command.
+  generateResourcesConfigFile.doFirst {
+    def assetsFolder = new File("${project.rootDir}/assets/")
+    def lwjgl3 = project(':lwjgl3')
+    def resFolder = new File("${lwjgl3.projectDir}/src/main/resources/META-INF/native-image/${lwjgl3.ext.appName}")
+    resFolder.mkdirs()
+    def resFile = new File(resFolder, "resource-config.json")
+    resFile.delete()
+    resFile.append(
+            """{
+  "resources":{
+  "includes":[
+    {
+      "pattern": ".*(""")
+    // This adds every filename in the assets/ folder to a pattern that adds those files as resources.
+    fileTree(assetsFolder).each {
+      // The backslash-Q and backslash-E escape the start and end of a literal string, respectively.
+      resFile.append("\\\\Q${it.name}\\\\E|")
+    }
+    // We also match all of the window icon images this way and the font files that are part of libGDX.
+    resFile.append(
+            """libgdx.+\\\\.png|lsans.+)"
+    }
+  ]},
+  "bundles":[]
+}"""
+    )
+  }
+}

BIN
lwjgl3/src/main/resources/libgdx128.png


BIN
lwjgl3/src/main/resources/libgdx16.png


BIN
lwjgl3/src/main/resources/libgdx32.png


BIN
lwjgl3/src/main/resources/libgdx64.png


+ 48 - 0
lwjgl3/src/src/main/java/me/lethunderhawk/lwjgl3/Lwjgl3Launcher.java

@@ -0,0 +1,48 @@
+package me.lethunderhawk.lwjgl3;
+
+import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
+import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
+import me.lethunderhawk.Main;
+
+/** Launches the desktop (LWJGL3) application. */
+public class Lwjgl3Launcher {
+    public static void main(String[] args) {
+        if (StartupHelper.startNewJvmIfRequired()) return; // This handles macOS support and helps on Windows.
+        createApplication();
+    }
+
+    private static Lwjgl3Application createApplication() {
+        return new Lwjgl3Application(new Main(), getDefaultConfiguration());
+    }
+
+    private static Lwjgl3ApplicationConfiguration getDefaultConfiguration() {
+        Lwjgl3ApplicationConfiguration configuration = new Lwjgl3ApplicationConfiguration();
+        configuration.setTitle("Smog");
+        //// Vsync limits the frames per second to what your hardware can display, and helps eliminate
+        //// screen tearing. This setting doesn't always work on Linux, so the line after is a safeguard.
+        configuration.useVsync(true);
+        //// Limits FPS to the refresh rate of the currently active monitor, plus 1 to try to match fractional
+        //// refresh rates. The Vsync setting above should limit the actual FPS to match the monitor.
+        configuration.setForegroundFPS(Lwjgl3ApplicationConfiguration.getDisplayMode().refreshRate + 1);
+        //// If you remove the above line and set Vsync to false, you can get unlimited FPS, which can be
+        //// useful for testing performance, but can also be very stressful to some hardware.
+        //// You may also need to configure GPU drivers to fully disable Vsync; this can cause screen tearing.
+
+        configuration.setWindowedMode(640, 480);
+        //// You can change these files; they are in lwjgl3/src/main/resources/ .
+        //// They can also be loaded from the root of assets/ .
+        configuration.setWindowIcon("libgdx128.png", "libgdx64.png", "libgdx32.png", "libgdx16.png");
+
+        //// This could improve compatibility with Windows machines with buggy OpenGL drivers, Macs
+        //// with Apple Silicon that have to emulate compatibility with OpenGL anyway, and more.
+        //// This uses the dependency `com.badlogicgames.gdx:gdx-lwjgl3-angle` to function.
+        //// You would need to add this line to lwjgl3/build.gradle , below the dependency on `gdx-backend-lwjgl3`:
+        ////     implementation "com.badlogicgames.gdx:gdx-lwjgl3-angle:$gdxVersion"
+        //// You can choose to add the following line and the mentioned dependency if you want; they
+        //// are not intended for games that use GL30 (which is compatibility with OpenGL ES 3.0).
+        //// Know that it might not work well in some cases.
+//        configuration.setOpenGLEmulation(Lwjgl3ApplicationConfiguration.GLEmulation.ANGLE_GLES20, 0, 0);
+
+        return configuration;
+    }
+}

+ 227 - 0
lwjgl3/src/src/main/java/me/lethunderhawk/lwjgl3/StartupHelper.java

@@ -0,0 +1,227 @@
+/*
+ * Copyright 2020 damios
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// Note, the above license and copyright applies to this file only.
+package me.lethunderhawk.lwjgl3;
+
+import com.badlogic.gdx.Version;
+import com.badlogic.gdx.backends.lwjgl3.Lwjgl3NativesLoader;
+
+import org.lwjgl.system.JNI;
+import org.lwjgl.system.linux.UNISTD;
+import org.lwjgl.system.macosx.LibC;
+import org.lwjgl.system.macosx.ObjCRuntime;
+
+import java.io.File;
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * A helper object for game startup, featuring three utilities related to LWJGL3 on various operating systems.
+ * <p>
+ * The utilities are as follows:
+ * <ul>
+ *  <li> Windows: Prevents a common crash related to LWJGL3's extraction of shared library files.</li>
+ *  <li> macOS: Spawns a child JVM process with {@code -XstartOnFirstThread} in the JVM args (if it was not already).
+ *  This is required for LWJGL3 to work on macOS.</li>
+ *  <li> Linux (NVIDIA GPUs only): Spawns a child JVM process with the {@code __GL_THREADED_OPTIMIZATIONS}
+ *  {@link System#getenv(String) Environment Variable} set to {@code 0} (if it was not already). This is required for
+ *  LWJGL3 to work on Linux with NVIDIA GPUs.</li>
+ * </ul>
+ * <a href="https://jvm-gaming.org/t/starting-jvm-on-mac-with-xstartonfirstthread-programmatically/57547">Based on this java-gaming.org post by kappa</a>
+ * @author damios
+ */
+public class StartupHelper {
+
+	private StartupHelper() {}
+
+	private static final String JVM_RESTARTED_ARG = "jvmIsRestarted";
+
+	/**
+	 * Must only be called on Linux. Check OS first (or use short-circuit evaluation)!
+	 * @return whether NVIDIA drivers are present on Linux.
+	 */
+	public static boolean isLinuxNvidia() {
+		String[] drivers = new File("/proc/driver").list(
+			(dir, path) -> path.toUpperCase(Locale.ROOT).contains("NVIDIA")
+		);
+		if (drivers == null) return false;
+		return drivers.length > 0;
+	}
+
+	/**
+	 * Applies the utilities as described by {@link StartupHelper}'s Javadoc.
+	 * <p>
+	 * All {@link System#getenv() Environment Variables} are copied to the child JVM process (if it is spawned), as
+	 * specified by {@link ProcessBuilder#environment()}; the same applies for
+	 * {@link System#getProperties() System Properties}.
+	 * <p>
+	 * <b>Usage:</b>
+	 * <pre><code>
+	 * public static void main(String[] args) {
+	 * 	 if (StartupHelper.startNewJvmIfRequired()) return;
+	 * 	 // ... The rest of main() goes here, as normal.
+	 * }
+	 * </code></pre>
+	 * @return whether a child JVM process was spawned or not.
+	 */
+	public static boolean startNewJvmIfRequired() {
+		return startNewJvmIfRequired(true);
+	}
+
+	/**
+	 * Applies the utilities as described by {@link StartupHelper}'s Javadoc.
+	 * <p>
+	 * All {@link System#getenv() Environment Variables} are copied to the child JVM process (if it is spawned), as
+	 * specified by {@link ProcessBuilder#environment()}; the same applies for
+	 * {@link System#getProperties() System Properties}.
+	 * <p>
+	 * <b>Usage:</b>
+	 * <pre><code>
+	 * public static void main(String[] args) {
+	 *   // The parameter on the next line could instead be false if you don't want to inherit IO.
+	 * 	 if (StartupHelper.startNewJvmIfRequired(true)) return;
+	 * 	 // ... The rest of main() goes here, as normal.
+	 * }
+	 * </code></pre>
+	 * @param inheritIO whether I/O should be inherited in the child JVM process. Please note that enabling this will
+	 *                  block the thread until the child JVM process stops executing.
+	 * @return whether a child JVM process was spawned or not.
+	 */
+	public static boolean startNewJvmIfRequired(boolean inheritIO) {
+		String osName = System.getProperty("os.name").toLowerCase(Locale.ROOT);
+		if (osName.contains("mac")) return startNewJvm0(/*isMac =*/ true, inheritIO);
+		if (osName.contains("windows")) {
+			// Here, we are trying to work around an issue with how LWJGL3 loads its extracted .dll files.
+			// By default, LWJGL3 extracts to the directory specified by "java.io.tmpdir": usually, the user's home.
+			// If the user's name has non-ASCII (or some non-alphanumeric) characters in it, that would fail.
+			// By extracting to the relevant "ProgramData" folder, which is usually "C:\ProgramData", we avoid this.
+			// We also temporarily change the "user.name" property to one without any chars that would be invalid.
+			// We revert our changes immediately after loading LWJGL3 natives.
+			String programData = System.getenv("ProgramData");
+			if (programData == null) programData = "C:\\Temp"; // if ProgramData isn't set, try some fallback.
+			String prevTmpDir = System.getProperty("java.io.tmpdir", programData);
+			String prevUser = System.getProperty("user.name", "libGDX_User");
+			System.setProperty("java.io.tmpdir", programData + "\\libGDX-temp");
+			System.setProperty(
+				"user.name",
+				("User_" + prevUser.hashCode() + "_GDX" + Version.VERSION).replace('.', '_')
+			);
+			Lwjgl3NativesLoader.load();
+			System.setProperty("java.io.tmpdir", prevTmpDir);
+			System.setProperty("user.name", prevUser);
+			return false;
+		}
+		return startNewJvm0(/*isMac =*/ false, inheritIO);
+	}
+
+	private static final String MAC_JRE_ERR_MSG = "A Java installation could not be found. If you are distributing this app with a bundled JRE, be sure to set the '-XstartOnFirstThread' argument manually!";
+	private static final String LINUX_JRE_ERR_MSG = "A Java installation could not be found. If you are distributing this app with a bundled JRE, be sure to set the environment variable '__GL_THREADED_OPTIMIZATIONS' to '0'!";
+	private static final String CHILD_LOOP_ERR_MSG = "The current JVM process is a spawned child JVM process, but StartupHelper has attempted to spawn another child JVM process! This is a broken state, and should not normally happen! Your game may crash or not function properly!";
+
+	/**
+	 * Spawns a child JVM process if on macOS, or on Linux with NVIDIA drivers.
+	 * <p>
+	 * All {@link System#getenv() Environment Variables} are copied to the child JVM process (if it is spawned), as
+	 * specified by {@link ProcessBuilder#environment()}; the same applies for
+	 * {@link System#getProperties() System Properties}.
+	 * @param isMac whether the current OS is macOS. If this is `false` then the current OS is assumed to be Linux (and
+	 *             an immediate check for NVIDIA drivers is performed).
+	 * @param inheritIO whether I/O should be inherited in the child JVM process. Please note that enabling this will
+	 *                 block the thread until the child JVM process stops executing.
+	 * @return whether a child JVM process was spawned or not.
+	 */
+	public static boolean startNewJvm0(boolean isMac, boolean inheritIO) {
+		long processID = getProcessID(isMac);
+		if (!isMac) {
+			// No need to restart non-NVIDIA Linux
+			if (!isLinuxNvidia()) return false;
+			// check whether __GL_THREADED_OPTIMIZATIONS is already disabled
+			if ("0".equals(System.getenv("__GL_THREADED_OPTIMIZATIONS"))) return false;
+		} else {
+			// There is no need for -XstartOnFirstThread on Graal native image
+			if (!System.getProperty("org.graalvm.nativeimage.imagecode", "").isEmpty()) return false;
+
+			// Checks if we are already on the main thread, such as from running via Construo.
+			long objcMsgSend = ObjCRuntime.getLibrary().getFunctionAddress("objc_msgSend");
+			long nsThread = ObjCRuntime.objc_getClass("NSThread");
+			long currentThread = JNI.invokePPP(nsThread, ObjCRuntime.sel_getUid("currentThread"), objcMsgSend);
+			boolean isMainThread = JNI.invokePPZ(currentThread, ObjCRuntime.sel_getUid("isMainThread"), objcMsgSend);
+			if (isMainThread) return false;
+
+			if ("1".equals(System.getenv("JAVA_STARTED_ON_FIRST_THREAD_" + processID))) return false;
+		}
+
+		// Check whether this JVM process is a child JVM process already.
+		// This state shouldn't usually be reachable, but this stops us from endlessly spawning new child JVM processes.
+		if ("true".equals(System.getProperty(JVM_RESTARTED_ARG))) {
+			System.err.println(CHILD_LOOP_ERR_MSG);
+			return false;
+		}
+
+		// Spawn the child JVM process with updated environment variables or JVM args
+		List<String> jvmArgs = new ArrayList<>();
+		// The following line is used assuming you target Java 8, the minimum for LWJGL3.
+		String javaExecPath = System.getProperty("java.home") + "/bin/java";
+		// If targeting Java 9 or higher, you could use the following instead of the above line:
+		//String javaExecPath = ProcessHandle.current().info().command().orElseThrow()
+		if (!(new File(javaExecPath).exists())) {
+			System.err.println(getJreErrMsg(isMac));
+			return false;
+		}
+
+		jvmArgs.add(javaExecPath);
+		if (isMac) jvmArgs.add("-XstartOnFirstThread");
+		jvmArgs.add("-D" + JVM_RESTARTED_ARG + "=true");
+		jvmArgs.addAll(ManagementFactory.getRuntimeMXBean().getInputArguments());
+		jvmArgs.add("-cp");
+		jvmArgs.add(System.getProperty("java.class.path"));
+		String mainClass = System.getenv("JAVA_MAIN_CLASS_" + processID);
+		if (mainClass == null) {
+			StackTraceElement[] trace = Thread.currentThread().getStackTrace();
+			if (trace.length > 0) mainClass = trace[trace.length - 1].getClassName();
+			else {
+				System.err.println("The main class could not be determined.");
+				return false;
+			}
+		}
+		jvmArgs.add(mainClass);
+
+		try {
+			ProcessBuilder processBuilder = new ProcessBuilder(jvmArgs);
+			if (!isMac) processBuilder.environment().put("__GL_THREADED_OPTIMIZATIONS", "0");
+
+			if (!inheritIO) processBuilder.start();
+			else processBuilder.inheritIO().start().waitFor();
+		} catch (Exception e) {
+			System.err.println("There was a problem restarting the JVM.");
+			// noinspection CallToPrintStackTrace
+			e.printStackTrace();
+		}
+
+		return true;
+	}
+
+	private static String getJreErrMsg(boolean isMac) {
+		if (isMac) return MAC_JRE_ERR_MSG;
+		else return LINUX_JRE_ERR_MSG;
+	}
+
+	private static long getProcessID(boolean isMac) {
+		if (isMac) return LibC.getpid();
+		else return UNISTD.getpid();
+	}
+}

+ 44 - 0
server/build.gradle

@@ -0,0 +1,44 @@
+apply plugin: 'application'
+
+
+java.sourceCompatibility = 21
+java.targetCompatibility = 21
+if (JavaVersion.current().isJava9Compatible()) {
+        compileJava.options.release.set(21)
+}
+
+application.mainClass = 'me.lethunderhawk.server.ServerLauncher'
+application.applicationName = appName
+eclipse.project.name = appName + '-server'
+
+dependencies {
+  implementation project(':shared')
+  implementation project(":core")
+  implementation "com.esotericsoftware:kryonet:2.22.0-RC1"
+}
+
+jar {
+  archiveBaseName.set(appName)
+// the duplicatesStrategy matters starting in Gradle 7.0; this setting works.
+  duplicatesStrategy = DuplicatesStrategy.EXCLUDE
+  dependsOn configurations.runtimeClasspath
+  from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
+// these "exclude" lines remove some unnecessary duplicate files in the output JAR.
+  exclude('META-INF/INDEX.LIST', 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA')
+  dependencies {
+    exclude('META-INF/INDEX.LIST', 'META-INF/maven/**')
+  }
+// setting the manifest makes the JAR runnable.
+// enabling native access helps avoid a warning when Java 24 or later runs the JAR.
+  manifest {
+    attributes 'Main-Class': application.mainClass, 'Enable-Native-Access': 'ALL-UNNAMED', 'Multi-Release': 'true'
+  }
+// this last step may help on some OSes that need extra instruction to make runnable JARs.
+  doLast {
+    file(archiveFile).setExecutable(true, false)
+  }
+}
+
+// Equivalent to the jar task; here for compatibility with gdx-setup.
+task dist(dependsOn: [jar]) {
+}

+ 42 - 0
server/src/main/java/me/lethunderhawk/server/GameServer.java

@@ -0,0 +1,42 @@
+package me.lethunderhawk.server;
+
+import com.esotericsoftware.kryonet.Connection;
+import com.esotericsoftware.kryonet.Listener;
+import com.esotericsoftware.kryonet.Server;
+import me.lethunderhawk.network.NetworkRegister;
+import me.lethunderhawk.network.Packets;
+
+import java.io.IOException;
+
+public class GameServer {
+
+    private final Server server;
+
+    public GameServer() throws IOException {
+
+        server = new Server();
+
+        registerPackets();
+
+        server.start();
+
+        server.bind(54555, 54777);
+
+        server.addListener(new Listener() {
+
+            @Override
+            public void received(Connection connection, Object object) {
+                if(object instanceof Packets.PlayerLoginPacket packet) {
+                    server.sendToAllExceptUDP(connection.getID(), packet);
+                }
+                if(object instanceof Packets.PlayerPositionPacket packet) {
+                    server.sendToAllExceptUDP(connection.getID(), packet);
+                }
+            }
+        });
+    }
+
+    private void registerPackets() {
+        NetworkRegister.register(server.getKryo());
+    }
+}

+ 16 - 0
server/src/main/java/me/lethunderhawk/server/ServerLauncher.java

@@ -0,0 +1,16 @@
+package me.lethunderhawk.server;
+
+/** Launches the server application. */
+public class ServerLauncher {
+
+    public static void main(String[] args) {
+
+        try {
+
+            new GameServer();
+            System.out.println("Server gestartet.");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 5 - 0
shared/build.gradle

@@ -0,0 +1,5 @@
+eclipse.project.name = appName + '-shared'
+
+dependencies {
+
+}