mirror of
https://github.com/DaanVandenBosch/phantasmal-world.git
synced 2025-04-04 06:28:28 +08:00
Updated README and FEATURES to reflect Kotlin-related changes and bugfixes.
This commit is contained in:
parent
29d13697a1
commit
724e324fca
@ -156,8 +156,6 @@ Features that are in ***bold italics*** are planned but not yet implemented.
|
||||
|
||||
## Bugs
|
||||
|
||||
- [Script Assembly Editor](#script-assembly-editor): Go to definition doesn't work in RT (#231), PW2
|
||||
(#234) and Magnitude of Metal (#1, can jump to label 207 from line 433, but not from line 465)
|
||||
- When a modal dialog is open, global keybindings should be disabled
|
||||
- Entities with rendering issues:
|
||||
- Caves 4 Button door
|
||||
@ -175,4 +173,3 @@ Features that are in ***bold italics*** are planned but not yet implemented.
|
||||
- Desert Fixed Type Box (Breakable Crystals)
|
||||
- Merissa A
|
||||
- Merissa AA
|
||||
- [Event Actions](#Event Actions): Editing event actions can't be undone
|
||||
|
100
README.md
100
README.md
@ -4,7 +4,9 @@
|
||||
|
||||
## Developers
|
||||
|
||||
TODO: This entire section is out of date since porting PW to Kotlin.
|
||||
Phantasmal World is written in [Kotlin](https://kotlinlang.org/) and uses
|
||||
the [Gradle](https://gradle.org/) build tool. Much of the code
|
||||
is [multiplatform](https://kotlinlang.org/docs/multiplatform.html) and reusable as a library.
|
||||
|
||||
<a href="https://github.com/DaanVandenBosch/phantasmal-world/actions?query=workflow%3ATests">
|
||||
<img alt="Tests status" src="https://github.com/DaanVandenBosch/phantasmal-world/workflows/Tests/badge.svg">
|
||||
@ -20,82 +22,66 @@ See [features](./FEATURES.md) for a list of features, planned features and bugs.
|
||||
|
||||
### Getting Started
|
||||
|
||||
1. Install Node.js ([https://nodejs.org/](https://nodejs.org/))
|
||||
2. Install Yarn ([https://yarnpkg.com/](https://yarnpkg.com/))
|
||||
3. `cd` to the project directory
|
||||
4. Install dependencies with `yarn`
|
||||
5. Launch server on [http://localhost:1623/](http://localhost:1623/) with `yarn start`
|
||||
6. [src/index.ts](src/index.ts) is the application's entry point
|
||||
1. Install Java 11+ (e.g. [AdoptOpenJDK](https://adoptopenjdk.net/)
|
||||
or [GraalVM](https://www.graalvm.org/downloads/))
|
||||
2. `cd` to the project directory
|
||||
3. Launch webpack server on [http://localhost:1623/](http://localhost:1623/)
|
||||
with `./gradlew :web:run --continuous`
|
||||
4. [web/src/main/kotlin/world/phantasmal/web/Main.kt](web/src/main/kotlin/world/phantasmal/web/Main.kt)
|
||||
is the application's entry point
|
||||
|
||||
[IntelliJ IDEA](https://www.jetbrains.com/idea/download/) is recommended for development. IntelliJ
|
||||
setup:
|
||||
|
||||
1. Use Ctrl-Alt-Shift-S to open the Project Structure window and select a JDK (you can let IntelliJ
|
||||
download a JDK if you don't have a compatible one installed)
|
||||
2. Configure the Gradle run task:
|
||||
1. In the Gradle window, right click web -> Tasks -> other -> run
|
||||
2. Click "Modify Run Configuration..."
|
||||
3. Add `--continuous` to the arguments field
|
||||
4. Click OK
|
||||
5. You can now start the webpack server from the main toolbar
|
||||
|
||||
### Exploring the Code Base
|
||||
|
||||
The code base is divided up into a [core](src/core) module, an [application](src/application) module
|
||||
and a module per tool (e.g. [quest_editor](src/quest_editor)). The core module contains the base
|
||||
code that the other modules depend on. The application module contains the
|
||||
[main application view](src/application/gui/ApplicationView.ts) that provides navigation between the
|
||||
different tools. The application view lazily loads and initializes the necessary modules. Each other
|
||||
module represents a tool such as the quest editor or the hunt optimizer.
|
||||
The code base is divided up into the following gradle subprojects.
|
||||
|
||||
#### Submodules
|
||||
#### core
|
||||
|
||||
All modules have an index.ts file that contains an initialization function. They then have several
|
||||
common submodules such as controllers, gui, model and stores and some module-specific submodules.
|
||||
Core contains the basic utilities that all other subprojects directly or indirectly depend on.
|
||||
|
||||
##### GUI
|
||||
#### lib
|
||||
|
||||
The gui submodule contains views with minimal logic. They simply display what their controller
|
||||
provides and forward user input to it. Their only dependency is the DOM and a single controller.
|
||||
Keeping logic out of the views makes the UI easier to test. We don't really need to test the views
|
||||
as they don't contain complex code, just testing the controller layer gives us confidence that the
|
||||
UI works. The only automatic tests for the gui layer are
|
||||
[snapshot tests](https://jestjs.io/docs/en/snapshot-testing).
|
||||
Lib contains PSO file format parsers, compression/decompression code, a PSO script
|
||||
assembler/disassembler and a work-in-progress script engine/VM. It also has a model of the PSO
|
||||
scripting bytecode and data flow analysis for it. This subproject can be used as a library in other
|
||||
projects.
|
||||
|
||||
##### Controllers
|
||||
#### observable
|
||||
|
||||
The controllers submodule contains the [controllers](src/core/controllers/Controller.ts) on which
|
||||
views depend. Usually the view-controller relationship is one-to-one, sometimes it's many-to-one
|
||||
(e.g. when a view has many subviews that work with the same data). A controller usually extracts
|
||||
data from a shared store and transforms it into a format which the view can easily consume.
|
||||
A full-fledged multiplatform implementation of the observer pattern.
|
||||
|
||||
##### Model
|
||||
#### test-utils
|
||||
|
||||
The model submodule contains observable model objects. Models expose read-only observable properties
|
||||
and allow their properties to be changed via setters which validate their inputs.
|
||||
Test utilities used by the other subprojects.
|
||||
|
||||
##### Stores
|
||||
#### [web](web/README.md)
|
||||
|
||||
The stores submodule contains shared data [stores](src/core/stores/Store.ts). Stores ensure that
|
||||
data is loaded when necessary and that the data is deduplicated. Stores also contain ephemeral
|
||||
shared state such as the currently selected entity in the quest editor.
|
||||
The actual Phantasmal World web application.
|
||||
|
||||
#### Some Interesting Parts of the Code Base
|
||||
#### webgui
|
||||
|
||||
Phantasmal contains parsers for many of the client's formats in
|
||||
[src/core/data_formats](src/core/data_formats). A model of the PSO scripting byte code and data flow
|
||||
analysis for it can be found in [src/core/data_formats/asm](src/core/data_formats/asm). The
|
||||
[src/quest_editor/scripting](src/quest_editor/scripting) directory contains an assembler,
|
||||
disassembler and (partly implemented) virtual machine.
|
||||
Web GUI toolkit used by Phantasmal World.
|
||||
|
||||
### Unit Tests
|
||||
|
||||
Run the unit tests with `yarn test` or `yarn test --watch` if you want the relevant tests to be
|
||||
re-run whenever a file is changed. The testing framework used is Jest.
|
||||
Run the unit tests with `./gradlew test`. JS tests are run with Karma and Mocha, JVM tests with
|
||||
Junit 5.
|
||||
|
||||
### Code Style, Linting and Formatting
|
||||
### Code Style and Formatting
|
||||
|
||||
Class/interface/type names are in `PascalCase` and all other identifiers are in `snake_case`.
|
||||
|
||||
ESLint and Prettier are used for linting and formatting. Run with `yarn lint` and/or configure your
|
||||
editor to use the ESLint/Prettier configuration.
|
||||
The Kotlin [coding conventions](https://kotlinlang.org/docs/coding-conventions.html) are used.
|
||||
|
||||
### Production Build
|
||||
|
||||
Create an optimized production build with `yarn build`.
|
||||
|
||||
### Optional Modules
|
||||
|
||||
### prs-rs
|
||||
|
||||
Provides faster PRS routines using WebAssembly. Build for WebPack with `yarn build_prs_rs_browser`.
|
||||
Build for Jest with `yarn build_prs_rs_testing`. Building requires
|
||||
[wasm-pack](https://github.com/rustwasm/wasm-pack).
|
||||
Create an optimized production build with `./gradlew :web:browserDistribution`.
|
||||
|
71
web/README.md
Normal file
71
web/README.md
Normal file
@ -0,0 +1,71 @@
|
||||
# web
|
||||
|
||||
This is the main Phantasmal World web application. It consists of several tools, each in their own
|
||||
package. Beside these packages there's also an application, core and externals package.
|
||||
|
||||
## Main Packages
|
||||
|
||||
### application
|
||||
|
||||
The application package contains the main application view that provides navigation between the
|
||||
different tools. The application view lazily loads and initializes the necessary tools.
|
||||
|
||||
### core
|
||||
|
||||
Contains code that is reused throughout the web project.
|
||||
|
||||
### externals
|
||||
|
||||
External declarations for NPM dependencies.
|
||||
|
||||
### huntOptimizer, questEditor, viewer
|
||||
|
||||
One main package per tool. Each tool is encapsulated in a PwTool implementation.
|
||||
|
||||
## Common Structure
|
||||
|
||||
The main packages all follow the same structure except for the externals package.
|
||||
|
||||
### widgets
|
||||
|
||||
The widgets package contains views with minimal logic. They simply display the models their
|
||||
controller provides and forward user input to their controller. Their only dependency is the DOM and
|
||||
a single controller.
|
||||
|
||||
Keeping logic out of the views makes the UI easier to test. We don't really need to have unit tests
|
||||
for the views as they don't contain complex code, just having unit tests from controller layer down
|
||||
and manually smoke testing the GUI layer gives us enough confidence that everything works.
|
||||
|
||||
### controllers
|
||||
|
||||
The controllers package contains the controllers on which views depend. Usually the view-controller
|
||||
relationship is one-to-one, sometimes it's many-to-one
|
||||
(e.g. when a view has many subviews that work with the same data). A controller usually extracts
|
||||
data from a shared store and transforms it into a format which the view can easily consume. A
|
||||
controller has no knowledge of the GUI layer.
|
||||
|
||||
### models
|
||||
|
||||
The models package contains observable model objects. Models expose read-only observable properties
|
||||
and allow their properties to be changed via setters which validate their inputs.
|
||||
|
||||
### stores
|
||||
|
||||
The stores package contains shared data stores. Stores ensure that data is loaded when necessary and
|
||||
that the data is deduplicated. Stores also contain ephemeral shared state such as the currently
|
||||
selected entity in the quest editor.
|
||||
|
||||
## Subprojects
|
||||
|
||||
### web:assembly-worker
|
||||
|
||||
Does analysis of the script assembly code and runs in a worker thread.
|
||||
|
||||
### web:assets-generation
|
||||
|
||||
This code is manually run to generate various assets used by web such as item lists, drop tables,
|
||||
quest lists, etc.
|
||||
|
||||
### web:shared
|
||||
|
||||
Contains code used by web, web:assembly-worker and web:assets-generation.
|
@ -6,13 +6,13 @@ import world.phantasmal.web.core.PwToolType
|
||||
import world.phantasmal.web.core.loading.AssetLoader
|
||||
import world.phantasmal.web.core.rendering.DisposableThreeRenderer
|
||||
import world.phantasmal.web.core.widgets.RendererWidget
|
||||
import world.phantasmal.web.viewer.controller.CharacterClassOptionsController
|
||||
import world.phantasmal.web.viewer.controller.ViewerController
|
||||
import world.phantasmal.web.viewer.controller.ViewerToolbarController
|
||||
import world.phantasmal.web.viewer.controllers.CharacterClassOptionsController
|
||||
import world.phantasmal.web.viewer.controllers.ViewerController
|
||||
import world.phantasmal.web.viewer.controllers.ViewerToolbarController
|
||||
import world.phantasmal.web.viewer.loading.CharacterClassAssetLoader
|
||||
import world.phantasmal.web.viewer.rendering.MeshRenderer
|
||||
import world.phantasmal.web.viewer.rendering.TextureRenderer
|
||||
import world.phantasmal.web.viewer.store.ViewerStore
|
||||
import world.phantasmal.web.viewer.stores.ViewerStore
|
||||
import world.phantasmal.web.viewer.widgets.CharacterClassOptionsWidget
|
||||
import world.phantasmal.web.viewer.widgets.ViewerToolbar
|
||||
import world.phantasmal.web.viewer.widgets.ViewerWidget
|
||||
|
@ -1,9 +1,9 @@
|
||||
package world.phantasmal.web.viewer.controller
|
||||
package world.phantasmal.web.viewer.controllers
|
||||
|
||||
import world.phantasmal.observable.value.Val
|
||||
import world.phantasmal.observable.value.plus
|
||||
import world.phantasmal.web.shared.dto.SectionId
|
||||
import world.phantasmal.web.viewer.store.ViewerStore
|
||||
import world.phantasmal.web.viewer.stores.ViewerStore
|
||||
import world.phantasmal.webui.controllers.Controller
|
||||
|
||||
class CharacterClassOptionsController(private val store: ViewerStore) : Controller() {
|
@ -1,8 +1,8 @@
|
||||
package world.phantasmal.web.viewer.controller
|
||||
package world.phantasmal.web.viewer.controllers
|
||||
|
||||
import world.phantasmal.observable.value.Val
|
||||
import world.phantasmal.web.viewer.models.CharacterClass
|
||||
import world.phantasmal.web.viewer.store.ViewerStore
|
||||
import world.phantasmal.web.viewer.stores.ViewerStore
|
||||
import world.phantasmal.webui.controllers.Tab
|
||||
import world.phantasmal.webui.controllers.TabContainerController
|
||||
|
@ -1,4 +1,4 @@
|
||||
package world.phantasmal.web.viewer.controller
|
||||
package world.phantasmal.web.viewer.controllers
|
||||
|
||||
import mu.KotlinLogging
|
||||
import org.w3c.files.File
|
||||
@ -11,7 +11,7 @@ import world.phantasmal.lib.fileFormats.ninja.*
|
||||
import world.phantasmal.lib.fileFormats.parseAfs
|
||||
import world.phantasmal.observable.value.Val
|
||||
import world.phantasmal.observable.value.mutableVal
|
||||
import world.phantasmal.web.viewer.store.ViewerStore
|
||||
import world.phantasmal.web.viewer.stores.ViewerStore
|
||||
import world.phantasmal.webui.controllers.Controller
|
||||
import world.phantasmal.webui.extension
|
||||
import world.phantasmal.webui.readFile
|
@ -9,7 +9,7 @@ import world.phantasmal.web.core.rendering.conversion.createAnimationClip
|
||||
import world.phantasmal.web.core.rendering.conversion.ninjaObjectToSkinnedMesh
|
||||
import world.phantasmal.web.core.times
|
||||
import world.phantasmal.web.externals.three.*
|
||||
import world.phantasmal.web.viewer.store.ViewerStore
|
||||
import world.phantasmal.web.viewer.stores.ViewerStore
|
||||
import kotlin.math.tan
|
||||
|
||||
class MeshRenderer(
|
||||
@ -58,11 +58,11 @@ class MeshRenderer(
|
||||
super.render()
|
||||
|
||||
animation?.let {
|
||||
val action = it.mixer.clipAction(it.clip)
|
||||
|
||||
if (!action.paused) {
|
||||
// TODO: Update current animation frame in store.
|
||||
}
|
||||
// TODO: Update current animation frame in store.
|
||||
// val action = it.mixer.clipAction(it.clip)
|
||||
//
|
||||
// if (!action.paused) {
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ import world.phantasmal.web.core.rendering.*
|
||||
import world.phantasmal.web.core.rendering.Renderer
|
||||
import world.phantasmal.web.core.rendering.conversion.xvrTextureToThree
|
||||
import world.phantasmal.web.externals.three.*
|
||||
import world.phantasmal.web.viewer.store.ViewerStore
|
||||
import world.phantasmal.web.viewer.stores.ViewerStore
|
||||
import world.phantasmal.webui.obj
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.max
|
||||
|
@ -1,4 +1,4 @@
|
||||
package world.phantasmal.web.viewer.store
|
||||
package world.phantasmal.web.viewer.stores
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
@ -4,7 +4,7 @@ import kotlinx.coroutines.launch
|
||||
import org.w3c.dom.Node
|
||||
import world.phantasmal.observable.value.value
|
||||
import world.phantasmal.web.shared.dto.SectionId
|
||||
import world.phantasmal.web.viewer.controller.CharacterClassOptionsController
|
||||
import world.phantasmal.web.viewer.controllers.CharacterClassOptionsController
|
||||
import world.phantasmal.webui.dom.div
|
||||
import world.phantasmal.webui.dom.table
|
||||
import world.phantasmal.webui.dom.td
|
||||
|
@ -2,7 +2,7 @@ package world.phantasmal.web.viewer.widgets
|
||||
|
||||
import kotlinx.coroutines.launch
|
||||
import org.w3c.dom.Node
|
||||
import world.phantasmal.web.viewer.controller.ViewerToolbarController
|
||||
import world.phantasmal.web.viewer.controllers.ViewerToolbarController
|
||||
import world.phantasmal.webui.dom.Icon
|
||||
import world.phantasmal.webui.dom.div
|
||||
import world.phantasmal.webui.widgets.*
|
||||
|
@ -2,8 +2,8 @@ package world.phantasmal.web.viewer.widgets
|
||||
|
||||
import kotlinx.coroutines.launch
|
||||
import org.w3c.dom.Node
|
||||
import world.phantasmal.web.viewer.controller.ViewerController
|
||||
import world.phantasmal.web.viewer.controller.ViewerTab
|
||||
import world.phantasmal.web.viewer.controllers.ViewerController
|
||||
import world.phantasmal.web.viewer.controllers.ViewerTab
|
||||
import world.phantasmal.webui.dom.div
|
||||
import world.phantasmal.webui.widgets.TabContainer
|
||||
import world.phantasmal.webui.widgets.Widget
|
||||
|
Loading…
Reference in New Issue
Block a user