Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 11 additions & 48 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build Multi-Platform JavaFX
name: Build Multi-Platform

on:
push:
Expand All @@ -8,73 +8,36 @@ on:

jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
name: Linux-x64
file_suffix: linux-x64
java_arch: x64
- os: windows-latest
name: Windows-x64
file_suffix: win-x64
java_arch: x64
- os: macos-latest
name: macOS-arm64 (Apple Silicon)
file_suffix: mac-arm64
java_arch: aarch64

runs-on: ${{ matrix.os }}
name: Build on ${{ matrix.name }}
runs-on: ubuntu-latest
name: Build Universal Jar

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up JDK 21 (${{ matrix.java_arch }})
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
architecture: ${{ matrix.java_arch }}

- name: Grant execute permission for gradlew
if: runner.os != 'Windows'
run: chmod +x gradlew

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4

- name: Build Client with Gradle
run: ./gradlew shadowJar jpackage

- name: Build Server
if: matrix.os == 'ubuntu-latest'
run: ./gradlew buildServer
- name: Build Client (ShadowJar) & Server
run: ./gradlew shadowJar buildServer

- name: Upload Shadow Jar
- name: Upload Client Shadow Jar
uses: actions/upload-artifact@v4
with:
name: TheEndlessWeave-${{ matrix.file_suffix }}-ShadowJar
path: build/libs/*-all.jar
name: TheEndlessWeave-Client-Universal
path: build/libs/*-client.jar

- name: Upload Server Jar
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v4
with:
name: TheEndlessWeave-Server
path: build/libs/*-server.jar

- name: Upload JPackage Installers
uses: actions/upload-artifact@v4
with:
name: TheEndlessWeave-${{ matrix.file_suffix }}-Installer
if-no-files-found: error
path: |
build/jpackage/*.exe
build/jpackage/*.msi
build/jpackage/*.dmg
build/jpackage/*.pkg
build/jpackage/*.deb
build/jpackage/*.rpm
name: TheEndlessWeave-Server-x64
path: build/libs/*-server.jar
35 changes: 20 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,18 @@

---
## Client
Требуется 64бит железо (спасибо javafx). Есть два пути билда:
- ShadowJar (всё в одной Jar) - `./gradlew shadowJar`
- бинарные файлы (через установщик или напрямую через папку с нативами) - `./gradlew jpackage`
Собрать полный jar со всеми бинарниками под архитектуру - `./gradlew shadowJar`

> ! Для windows может потребоваться тулкит чтобы собрать бинарные (`.\gralew jpackage`) файлы.

> ! Андроид билды не собираются в actions, но их можно собрать самому на телефоне в termux. хоть это и не имеет смысла на текущий момент, ну ладно.
---
## Server
Вы можете отдельно собрать только сервер, он кроссплатформленный и не зависит от архитектуры (может быть x32 итд)
Вы можете отдельно собрать только сервер.
```shell
./gradlew buildServer
```
Также сервер можно запустить из клиента:
```shell
java -jar filename-client.jar --server
```

---

Expand All @@ -34,19 +33,25 @@
- [X] Сделать Game абсолютно независимым, чтобы мог быть инициализирован как клиентом, так и сервером
- [X] Изменить архитектуру проекта на core (общее: компоненты, системы, генератор карты), client (текущий view) и server (серверный цикл)
- [X] Сделать минимальный Hi Hello сетевой стек.
- [ ] Адаптировать логику клиента и сервера для работы с сетью
- [ ] (!) клиент НЕ должен самостоятельно вызывать что-либо в Game, он должен отправлять пакет и получать подтверждение
- [X] Адаптировать логику клиента и сервера для работы с сетью
- [X] (!) клиент НЕ должен самостоятельно вызывать что-либо в Game, он должен отправлять пакет и получать подтверждение
- [X] синхронизировать игровую карту (клиент отправляет параметры (GameData), сервер хавает)
- [X] если сервер НЕ должен возвращать карту, то пусть сервер передаст шанс рандома, чтобы клиент сам создал карту с таким рандомом.
- [ ] Перенести логику игры на интегрированный сервер. Это исправит многие боли, наверное. (связан с пунктом выше, синхронизация игровой карты)
- [ ] Перенести соло игру на интегрированный сервер.
- клиент инициализирует и запускает локальный сервер в GameScreen
- [ ] конфиг генерации мира с клиента должен
- [ ] НеЗабитьНеЗабитьНеЗабитьНеЗабитьНеЗабитьНеЗабитьНеЗабитьНеЗабитьНеЗабить
- [ ] Hello LibGDX!
- Javafx слишком много срёт на слабых устройствах и в целом не подходит для текущих целей. нужно переписать рендер:
- [ ] `client.controllers`
- [ ] `client.custom.*`
- [ ] `client.systems.<classname.toLowerCase().equals("render")>`
- [ ] создать ветку и настроить `build.gradle.kts`.
- [ ] ...
- [X] `client.controllers` -> `client.screens`
- [X] `client.custom.*`
- [X] `client.systems.<classname.toLowerCase().equals("render")>`
- [X] создать ветку и настроить `build.gradle.kts`.
- Баги/проблемы (исправить)
- [ ] Из-за написанного кода под javafx, на клиенте могут возникать проблемы с логикой из-за другой системы координат в libgdx, например, при просчёте логики полёта пуль, необходимо домножать скорость на размер тайлов.
- [ ] сервер не удаляет игрока, если он отключился
- [ ] клиент рендерит других игроков как врагов
- [ ] ui не масштабируется при изменении размера окна.

---

Expand Down
130 changes: 43 additions & 87 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,18 @@ import java.util.Date
plugins {
java
application
id("org.javamodularity.moduleplugin") version "1.8.15"
id("org.openjfx.javafxplugin") version "0.0.13"
id("org.beryx.jlink") version "3.2.0"
id("com.github.johnrengelman.shadow") version "8.1.1"
}

group = "xyz.samiker"
version = "0.2.0"
version = "0.4.0"

val gdxVersion = "1.14.0"

repositories {
mavenCentral()
}

sourceSets {
main {
resources {
srcDir(layout.buildDirectory.dir("resources/generateResourceManifest"))
}
}
maven { url = uri("https://oss.sonatype.org/content/repositories/snapshots/") }
maven { url = uri("https://oss.sonatype.org/content/repositories/releases/") }
}

java {
Expand All @@ -30,28 +24,30 @@ java {
}
}

tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
}

application {
mainModule.set("xyz.samiker.theendlessweave")
mainClass.set("xyz.samiker.theendlessweave.Launcher")
}

javafx {
version = "21.0.6"
modules = listOf("javafx.controls", "javafx.fxml", "javafx.media")
}

dependencies {
implementation("org.controlsfx:controlsfx:11.2.1")
implementation("com.badlogicgames.gdx:gdx:$gdxVersion")
implementation("com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion")
implementation("com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop")
implementation("com.esotericsoftware:kryonet:2.22.0-RC1")
}

tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
}

tasks.named<JavaExec>("run") {
if (org.gradle.internal.os.OperatingSystem.current().isMacOsX) {
jvmArgs("-XstartOnFirstThread")
}
}

tasks.register<Jar>("buildServer") {
group = "build"
description = "билдит сервер без всякого fx говна"
description = "Билдит сервер без графического бэкенда и нативов"

archiveClassifier.set("server")

Expand All @@ -61,34 +57,34 @@ tasks.register<Jar>("buildServer") {

from(sourceSets.main.get().output) {
exclude("xyz/samiker/theendlessweave/client/**")

exclude("assets/**")
exclude("css/**")
exclude("fxml/**")
exclude("*.dll", "*.so", "*.dylib")
}

val serverClasspath = configurations.runtimeClasspath.get().filter { file ->
val name = file.name.lowercase()
!name.contains("javafx") &&
!name.contains("controlsfx") &&
!name.contains("native") &&
!name.contains("win") &&
!name.contains("mac") &&
!name.contains("linux")
!name.contains("gdx-backend-lwjgl3") &&
!name.contains("natives")
}

from(serverClasspath.map { if (it.isDirectory) it else zipTree(it) }) {
exclude("module-info.class")
exclude("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA")
exclude("META-INF/MANIFEST.MF")
exclude("**/*.dll", "**/*.so", "**/*.dylib")
exclude("module-info.class")
}

duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

tasks.withType<Test> {
useJUnitPlatform()
tasks.named<com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar>("shadowJar") {
archiveClassifier.set("client")
configurations = listOf(project.configurations.runtimeClasspath.get())

mergeServiceFiles()

manifest {
attributes["Main-Class"] = "xyz.samiker.theendlessweave.Launcher"
}
}

tasks.register("generateResourceManifest") {
Expand All @@ -104,7 +100,6 @@ tasks.register("generateResourceManifest") {

doLast {
println("Generating resource manifest to: ${manifestFile.asFile.path}")

val manifestContent = StringBuilder()
manifestContent.append("# Resource Manifest\n")
manifestContent.append("# Generated on: ${Date()}\n\n")
Expand All @@ -116,62 +111,23 @@ tasks.register("generateResourceManifest") {
manifestContent.append("resource.path=${relativePath.replace(File.separatorChar, '/')}\n\n")
}
}

outputDir.get().asFile.mkdirs()
manifestFile.asFile.writeText(manifestContent.toString())
}
}

tasks.named("processResources") {
dependsOn(tasks.named("generateResourceManifest"))
}

tasks.register<Jar>("shadowJar") {
group = "build"
description = "Builds an uber-jar (fat jar) with all dependencies."

archiveClassifier.set("all")

manifest {
attributes["Main-Class"] = "xyz.samiker.theendlessweave.Launcher"
}

from(sourceSets.main.get().output)

from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) {
exclude("module-info.class", "META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA", "META-INF/substrate/config/*", "META-INF/LICENSE", "META-INF/NOTICE")
sourceSets {
main {
resources {
srcDir(layout.buildDirectory.dir("resources/generateResourceManifest"))
}
}

duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

jlink {
imageZip.set(layout.buildDirectory.file("/distributions/app-${javafx.platform.classifier}.zip"))
options.set(listOf("--strip-debug", "--compress", "zip-8", "--no-header-files", "--no-man-pages"))
launcher {
name = "TheEndlessWeave"
}

val javaToolchains = project.extensions.getByType(JavaToolchainService::class)
val javaLauncher = javaToolchains.launcherFor(java.toolchain)
javaHome.set(javaLauncher.map { it.metadata.installationPath })

jpackage {
imageName = "TheEndlessWeave"
if (org.gradle.internal.os.OperatingSystem.current().isMacOsX) {
val ver = version as String
appVersion = if (ver.startsWith("0.")) "1" + ver.substring(1) else ver
} else {
appVersion = version as String?
}
tasks.named("processResources") {
dependsOn(tasks.named("generateResourceManifest"))
}

if (org.gradle.internal.os.OperatingSystem.current().isWindows) {
installerOptions = listOf(
"--win-shortcut",
"--win-menu",
"--win-dir-chooser",
"--win-menu-group", "The Endless Weave"
)
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
24 changes: 0 additions & 24 deletions src/main/java/module-info.java

This file was deleted.

Loading