From 59c868f568d15b070a5b277b5a9a5f697a9dc649 Mon Sep 17 00:00:00 2001 From: Filip Pajic Date: Wed, 19 Jun 2024 12:13:20 +0200 Subject: [PATCH] chore: separate client and rendering components to separate package --- packages/webcave-client/package.json | 20 +++++++++ packages/webcave-client/rollup.config.js | 16 ++++++++ packages/webcave-client/src/index.d.ts | 1 + packages/webcave-client/src/index.ts | 9 ++++ .../render => webcave-client/src}/player.ts | 41 ++++++++++++------- .../render => webcave-client/src}/renderer.ts | 29 ++++++++----- .../src/shared}/controls.ts | 4 +- .../src/shared}/ui.ts | 0 .../src/shared}/webgl.ts | 0 packages/webcave-client/src/types/gl.ts | 17 ++++++++ packages/webcave-client/src/types/util.ts | 9 ++++ packages/webcave-client/tsconfig.json | 14 +++++++ packages/webcave-client/tsconfig.lib.json | 10 +++++ packages/webcave-core/package.json | 2 +- packages/webcave-core/src/block.ts | 1 - packages/webcave-core/src/index.ts | 16 ++++++-- packages/webcave-core/src/material.ts | 5 ++- packages/webcave-core/src/shared/helpers.ts | 11 +++-- packages/webcave-core/src/types/chunk.ts | 2 +- packages/webcave-core/src/types/game.ts | 15 +++++++ packages/webcave-core/src/types/gl.ts | 18 -------- packages/webcave-core/src/types/material.ts | 3 +- packages/webcave-core/src/world.ts | 8 ++-- packages/webcave-core/tsconfig.lib.json | 4 +- packages/webcave-example-client/package.json | 3 +- .../src/WebCave/WebCave.tsx | 5 +-- .../src/WebCave/WebCave.types.ts | 7 +++- tsconfig.json | 4 +- yarn.lock | 7 +--- 29 files changed, 204 insertions(+), 77 deletions(-) create mode 100644 packages/webcave-client/package.json create mode 100644 packages/webcave-client/rollup.config.js create mode 100644 packages/webcave-client/src/index.d.ts create mode 100644 packages/webcave-client/src/index.ts rename packages/{webcave-core/src/render => webcave-client/src}/player.ts (94%) rename packages/{webcave-core/src/render => webcave-client/src}/renderer.ts (98%) rename packages/{webcave-core/src/render => webcave-client/src/shared}/controls.ts (85%) rename packages/{webcave-core/src/render => webcave-client/src/shared}/ui.ts (100%) rename packages/{webcave-core/src/render => webcave-client/src/shared}/webgl.ts (100%) create mode 100644 packages/webcave-client/src/types/gl.ts create mode 100644 packages/webcave-client/src/types/util.ts create mode 100644 packages/webcave-client/tsconfig.json create mode 100644 packages/webcave-client/tsconfig.lib.json create mode 100644 packages/webcave-core/src/types/game.ts diff --git a/packages/webcave-client/package.json b/packages/webcave-client/package.json new file mode 100644 index 0000000..64a922c --- /dev/null +++ b/packages/webcave-client/package.json @@ -0,0 +1,20 @@ +{ + "name": "@acid-info/webcave-client", + "version": "0.0.0", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "rimraf dist && rollup --config" + }, + "dependencies": { + "@types/react": "^18.2.66", + "gl-matrix": "3.4.3", + "rollup": "^2.60.2", + "rollup-plugin-typescript2": "^0.31.1", + "tslib": "^2.3.1", + "typescript": "^5.4.5" + }, + "devDependencies": { + "rimraf": "^3.0.2" + } +} diff --git a/packages/webcave-client/rollup.config.js b/packages/webcave-client/rollup.config.js new file mode 100644 index 0000000..5c1e2ef --- /dev/null +++ b/packages/webcave-client/rollup.config.js @@ -0,0 +1,16 @@ +import typescript from 'rollup-plugin-typescript2'; + +export default { + input: ["src/index.ts"], + output: [ + { + dir: "dist", + entryFileNames: "[name].js", + format: "cjs", + exports: "named", + } + ], + plugins: [ + typescript(), + ] +}; diff --git a/packages/webcave-client/src/index.d.ts b/packages/webcave-client/src/index.d.ts new file mode 100644 index 0000000..8d231e2 --- /dev/null +++ b/packages/webcave-client/src/index.d.ts @@ -0,0 +1 @@ +export type * from "./index" \ No newline at end of file diff --git a/packages/webcave-client/src/index.ts b/packages/webcave-client/src/index.ts new file mode 100644 index 0000000..f9ba50f --- /dev/null +++ b/packages/webcave-client/src/index.ts @@ -0,0 +1,9 @@ +import Renderer from '../../webcave-client/src/renderer' +import Player from '../../webcave-client/src/player' + +export { + Renderer, + Player +} + +export { SELECTOR_WIDTH_PX } from "./shared/ui" \ No newline at end of file diff --git a/packages/webcave-core/src/render/player.ts b/packages/webcave-client/src/player.ts similarity index 94% rename from packages/webcave-core/src/render/player.ts rename to packages/webcave-client/src/player.ts index 3bdbd5a..1fa465b 100644 --- a/packages/webcave-core/src/render/player.ts +++ b/packages/webcave-client/src/player.ts @@ -1,17 +1,30 @@ -import World from '../world' -import Vector from '../shared/vector' -import { EMaterial, Material } from '../types/material' -import { MATERIALS } from '../material' -import { DynamicObject } from '../types/util' -import { EChatActions, ACTION_TO_KEYBOARD_KEY_MAP, EKeyboardActions, EActions } from './controls' -import { EMouseEvent } from '../types/controls' -import { CanvasPosition } from './webgl' -import Renderer from './renderer' -import { Collision, DirectedLine, Rectangle, Square, WebGLObject } from '../types/gl' -import { lineRectCollide, rectRectCollide } from '../shared/helpers' -import { SELECTOR_WIDTH_PX } from './ui' +import { + World, + Vector, + EMaterial, + Material, + MATERIALS, + EMouseEvent, + lineRectCollide, + rectRectCollide, + IPlayer, + Collision, + DirectedLine, + Rectangle, + Square, +} from "@acid-info/webcave-core/src" -class Player { +import { EChatActions, ACTION_TO_KEYBOARD_KEY_MAP, EKeyboardActions, EActions } from './shared/controls' +import { CanvasPosition } from './shared/webgl' +import Renderer from './renderer' +import { SELECTOR_WIDTH_PX } from './shared/ui' +import { DynamicObject } from './types/util' + +import { + WebGLObject, +} from "./types/gl" + +class Player implements IPlayer { public world: World; public canvas: HTMLCanvasElement; @@ -81,7 +94,7 @@ class Player { selector.onclick = () => { selector.style.opacity = "1.0"; - this.prevSelector.style.opacity = null; + this.prevSelector.style.opacity = ""; this.prevSelector = selector; this.buildMaterial = MATERIALS[mat]; diff --git a/packages/webcave-core/src/render/renderer.ts b/packages/webcave-client/src/renderer.ts similarity index 98% rename from packages/webcave-core/src/render/renderer.ts rename to packages/webcave-client/src/renderer.ts index 3a31a0e..2851b4e 100644 --- a/packages/webcave-core/src/render/renderer.ts +++ b/packages/webcave-client/src/renderer.ts @@ -1,14 +1,23 @@ -import { WebGl, WebGLBufferWithVertices, WebGLObject, WebGLTextureWithImage } from '../types/gl' +import { + World, + Vector, + MATERIALS, + EMaterial, + Block, + Chunk, + IRenderer, +} from '@acid-info/webcave-core/src' import { mat4 } from "gl-matrix" -import World from '../world' -import Vector from '../shared/vector' -import { MATERIALS } from '../material' -import { EMaterial } from '../types/material' -import Block from '../block' -import { WEB_GL_SOURCE } from './webgl' -import { Chunk } from '../types/chunk' +import { WEB_GL_SOURCE } from './shared/webgl' -class Renderer { +import { + WebGl, + WebGLBufferWithVertices, + WebGLObject, + WebGLTextureWithImage +} from "./types/gl" + +class Renderer implements IRenderer { public readonly canvas: HTMLCanvasElement; public readonly gl: WebGl; public program: WebGLProgram; @@ -146,7 +155,7 @@ class Renderer { this.gl.bindTexture( this.gl.TEXTURE_2D, this.texTerrain ); if ( chunks != null ) { - for ( var i = 0; i < chunks.length; i++ ) { + for ( let i = 0; i < chunks.length; i++ ) { if ( chunks[i].buffer != null ) this.drawBuffer( chunks[i].buffer ); } diff --git a/packages/webcave-core/src/render/controls.ts b/packages/webcave-client/src/shared/controls.ts similarity index 85% rename from packages/webcave-core/src/render/controls.ts rename to packages/webcave-client/src/shared/controls.ts index c32583c..d705d03 100644 --- a/packages/webcave-core/src/render/controls.ts +++ b/packages/webcave-client/src/shared/controls.ts @@ -1,4 +1,4 @@ -import { DynamicObject } from '../types/util' +import { AllKeysRequired, DynamicObject } from '../types/util' export enum EChatActions { OPEN_CHAT = 'OPEN_CHAT' @@ -14,7 +14,7 @@ export enum EKeyboardActions { export type EActions = EChatActions | EKeyboardActions; -export const ACTION_TO_KEYBOARD_KEY_MAP: DynamicObject = { +export const ACTION_TO_KEYBOARD_KEY_MAP: DynamicObject = { [EChatActions.OPEN_CHAT]: "t", [EKeyboardActions.MOVE_FORWARD]: "w", [EKeyboardActions.MOVE_BACKWARD]: "s", diff --git a/packages/webcave-core/src/render/ui.ts b/packages/webcave-client/src/shared/ui.ts similarity index 100% rename from packages/webcave-core/src/render/ui.ts rename to packages/webcave-client/src/shared/ui.ts diff --git a/packages/webcave-core/src/render/webgl.ts b/packages/webcave-client/src/shared/webgl.ts similarity index 100% rename from packages/webcave-core/src/render/webgl.ts rename to packages/webcave-client/src/shared/webgl.ts diff --git a/packages/webcave-client/src/types/gl.ts b/packages/webcave-client/src/types/gl.ts new file mode 100644 index 0000000..73374c0 --- /dev/null +++ b/packages/webcave-client/src/types/gl.ts @@ -0,0 +1,17 @@ +export type WebGl = WebGLRenderingContext & { + viewportWidth?: number; + viewportHeight?: number; +} + +export type WebGLTextureWithImage = WebGLTexture & { + image?: HTMLImageElement; +} + +export type WebGLBufferWithVertices = WebGLBuffer & { + vertices?: number; +} + +export type WebGLObject = { + texture: WebGLTexture, + model: WebGLBufferWithVertices +} \ No newline at end of file diff --git a/packages/webcave-client/src/types/util.ts b/packages/webcave-client/src/types/util.ts new file mode 100644 index 0000000..678f931 --- /dev/null +++ b/packages/webcave-client/src/types/util.ts @@ -0,0 +1,9 @@ +export type DynamicObject< + Value = any, + Key extends string | number = string, + AllKeysRequired = false, +> = AllKeysRequired extends true + ? { [K in Key]: Value } + : { [K in Key]?: Value } + +export type AllKeysRequired = true \ No newline at end of file diff --git a/packages/webcave-client/tsconfig.json b/packages/webcave-client/tsconfig.json new file mode 100644 index 0000000..4b928c1 --- /dev/null +++ b/packages/webcave-client/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "outDir": "./dist", + "declaration": true, + "allowSyntheticDefaultImports": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + } + ] +} diff --git a/packages/webcave-client/tsconfig.lib.json b/packages/webcave-client/tsconfig.lib.json new file mode 100644 index 0000000..5821ddc --- /dev/null +++ b/packages/webcave-client/tsconfig.lib.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist/out-tsc", + "lib": ["DOM", "DOM.Iterable"], + "types": ["node"] + }, + "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "node_modules", "./dist/**/*"], + "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] +} diff --git a/packages/webcave-core/package.json b/packages/webcave-core/package.json index 5bbe5ec..25f71c3 100644 --- a/packages/webcave-core/package.json +++ b/packages/webcave-core/package.json @@ -12,7 +12,7 @@ "rollup": "^2.60.2", "rollup-plugin-typescript2": "^0.31.1", "tslib": "^2.3.1", - "typescript": "^4.5.2" + "typescript": "^5.4.5" }, "devDependencies": { "rimraf": "^3.0.2" diff --git a/packages/webcave-core/src/block.ts b/packages/webcave-core/src/block.ts index 52532c0..ba3a088 100644 --- a/packages/webcave-core/src/block.ts +++ b/packages/webcave-core/src/block.ts @@ -9,7 +9,6 @@ class Block { return MATERIALS[id] } - // @TODO typings for lightmap public static pushVertices(vertices: number[], world: World, lightmap: any, x: number, y: number, z: number ) { let blocks = world.blocks; let blockLit = z >= lightmap[x][y]; diff --git a/packages/webcave-core/src/index.ts b/packages/webcave-core/src/index.ts index 3ffdb43..0478659 100644 --- a/packages/webcave-core/src/index.ts +++ b/packages/webcave-core/src/index.ts @@ -1,11 +1,19 @@ import World from "./world" -import Renderer from './render/renderer' -import Player from './render/player' import Physics from './physics' export { World, - Renderer, - Player, Physics } + +export { default as Block } from "./block" +export { MATERIALS } from "./material" + +export * from "./types/game" +export * from "./types/controls" +export * from "./types/material" +export * from "./types/chunk" +export * from "./types/gl" + +export * from "./shared/helpers" +export { default as Vector } from "./shared/vector" \ No newline at end of file diff --git a/packages/webcave-core/src/material.ts b/packages/webcave-core/src/material.ts index 6d7ca32..58e9f2c 100644 --- a/packages/webcave-core/src/material.ts +++ b/packages/webcave-core/src/material.ts @@ -6,7 +6,10 @@ export const MATERIALS: DynamicObject = { [EMaterial.AIR]: { id: EMaterial.AIR, spawnable: false, - transparent: true + transparent: true, + texture: () => { + return [0, 0, 0, 0] + } }, [EMaterial.BEDROCK]: { id: EMaterial.BEDROCK, diff --git a/packages/webcave-core/src/shared/helpers.ts b/packages/webcave-core/src/shared/helpers.ts index 4f06897..25c61c5 100644 --- a/packages/webcave-core/src/shared/helpers.ts +++ b/packages/webcave-core/src/shared/helpers.ts @@ -1,15 +1,18 @@ +import { Line, Rectangle, Square } from '../types/gl' + // lineRectCollide( line, rect ) // // Checks if an axis-aligned line and a bounding box overlap. // line = { y, x1, x2 } or line = { x, y1, y2 } // rect = { x, y, size } -import { Line, Rectangle, Square } from '../types/gl' - export function lineRectCollide(line: Line, rect: Square) { - if (line.y) + if (line.y) { return rect.y > line.y - rect.size/2 && rect.y < line.y + rect.size/2 && rect.x > line.x1 - rect.size/2 && rect.x < line.x2 + rect.size/2; - else + } else if (line.x) { return rect.x > line.x - rect.size/2 && rect.x < line.x + rect.size/2 && rect.y > line.y1 - rect.size/2 && rect.y < line.y2 + rect.size/2; + } + + return false; } // rectRectCollide( r1, r2 ) diff --git a/packages/webcave-core/src/types/chunk.ts b/packages/webcave-core/src/types/chunk.ts index 9978ac1..ee0eeb3 100644 --- a/packages/webcave-core/src/types/chunk.ts +++ b/packages/webcave-core/src/types/chunk.ts @@ -2,7 +2,7 @@ export type Chunk = { start: ChunkSize, end: ChunkSize, dirty: boolean, - buffer?: WebGLBuffer + buffer?: any } export type ChunkSize = [ diff --git a/packages/webcave-core/src/types/game.ts b/packages/webcave-core/src/types/game.ts new file mode 100644 index 0000000..6b7fe24 --- /dev/null +++ b/packages/webcave-core/src/types/game.ts @@ -0,0 +1,15 @@ +export interface IRenderer { + onBlockChanged: (x: number, y: number, z: number) => void; +} + +export interface IPlayer { + moving: boolean, + aniframe: number, + pitch: number, + x: number, + y: number, + z: number, + yaw: number, + nick: string, + nametag: any +} \ No newline at end of file diff --git a/packages/webcave-core/src/types/gl.ts b/packages/webcave-core/src/types/gl.ts index 9eecc70..bdb2ff2 100644 --- a/packages/webcave-core/src/types/gl.ts +++ b/packages/webcave-core/src/types/gl.ts @@ -1,21 +1,3 @@ -export type WebGl = WebGLRenderingContext & { - viewportWidth?: number; - viewportHeight?: number; -} - -export type WebGLTextureWithImage = WebGLTexture & { - image?: HTMLImageElement; -} - -export type WebGLBufferWithVertices = WebGLBuffer & { - vertices?: number; -} - -export type WebGLObject = { - texture: WebGLTexture, - model: WebGLBufferWithVertices -} - export type Square = { x: number, y: number, diff --git a/packages/webcave-core/src/types/material.ts b/packages/webcave-core/src/types/material.ts index 40b1340..f0cdb08 100644 --- a/packages/webcave-core/src/types/material.ts +++ b/packages/webcave-core/src/types/material.ts @@ -18,7 +18,6 @@ import { EDirection } from './controls' */ type TexturePositionTuple = [x1: number, y1: number, x2: number, y2: number]; -// @TODO typings for lightmap type GetTexture = (params: { world: World, lightmap: any, @@ -58,5 +57,5 @@ export type Material = { selflit?: boolean; gravity?: boolean; fluid?: boolean; - texture?: GetTexture + texture: GetTexture } \ No newline at end of file diff --git a/packages/webcave-core/src/world.ts b/packages/webcave-core/src/world.ts index 5054510..f3b17ad 100644 --- a/packages/webcave-core/src/world.ts +++ b/packages/webcave-core/src/world.ts @@ -2,8 +2,10 @@ import Vector from './shared/vector' import { MATERIALS } from './material' import { EMaterial, Material } from './types/material' import Block from './block' -import Renderer from './render/renderer' -import Player from './render/player' +import { + IRenderer as Renderer, + IPlayer as Player +} from "./types/game" /* * World container @@ -109,7 +111,7 @@ class World { * Returns a string representation of this world. * */ public toNetworkString() { - let blockArray = []; + let blockArray: string[] = []; for ( let x = 0; x < this.sx; x++ ) for ( let y = 0; y < this.sy; y++ ) diff --git a/packages/webcave-core/tsconfig.lib.json b/packages/webcave-core/tsconfig.lib.json index 9394fb6..9d8c74e 100644 --- a/packages/webcave-core/tsconfig.lib.json +++ b/packages/webcave-core/tsconfig.lib.json @@ -1,9 +1,9 @@ { - "extends": "./tsconfig.json", + "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "./dist/out-tsc", "types": ["node"] }, - "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "node_modules"], + "exclude": ["**/*.spec.ts", "**/*.spec.tsx", "node_modules", "./dist/**/*"], "include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"] } diff --git a/packages/webcave-example-client/package.json b/packages/webcave-example-client/package.json index 98207e5..98c4122 100644 --- a/packages/webcave-example-client/package.json +++ b/packages/webcave-example-client/package.json @@ -19,10 +19,11 @@ "@typescript-eslint/parser": "^7.2.0", "@vitejs/plugin-react": "^4.2.1", "@acid-info/webcave-core": "*", + "@acid-info/webcave-client": "*", "eslint": "^8.57.0", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.6", - "typescript": "^5.2.2", + "typescript": "^5.4.5", "vite": "^5.2.0", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0" diff --git a/packages/webcave-example-client/src/WebCave/WebCave.tsx b/packages/webcave-example-client/src/WebCave/WebCave.tsx index 9c4d9b0..a5f1420 100644 --- a/packages/webcave-example-client/src/WebCave/WebCave.tsx +++ b/packages/webcave-example-client/src/WebCave/WebCave.tsx @@ -1,12 +1,11 @@ import React from 'react' import { DEFAULT_WORLD_STRING } from './WebCave.defaultWorld.ts' import { WebCaveGameState } from './WebCave.types.ts' -import { Physics, Player, Renderer, World } from '@acid-info/webcave-core/src' +import { Physics, World } from '@acid-info/webcave-core/src' +import { Player, Renderer, SELECTOR_WIDTH_PX } from "@acid-info/webcave-client/src" import styled from '@emotion/styled' import { MouseEventHandler, useEffect, useRef, useState } from 'react' -const SELECTOR_WIDTH_PX = 40; - export default function WebCave() { const [gameState, setGameState] = useState() const webCaveRenderSurface = useRef(null); diff --git a/packages/webcave-example-client/src/WebCave/WebCave.types.ts b/packages/webcave-example-client/src/WebCave/WebCave.types.ts index a2a5bfe..66e14b0 100644 --- a/packages/webcave-example-client/src/WebCave/WebCave.types.ts +++ b/packages/webcave-example-client/src/WebCave/WebCave.types.ts @@ -1,9 +1,12 @@ import { Physics, - World, + World +} from '@acid-info/webcave-core/src' + +import { Renderer, Player -} from '@acid-info/webcave-core/src' +} from "@acid-info/webcave-client/src" export type WebCaveGameState = { world: World diff --git a/tsconfig.json b/tsconfig.json index 61d64ad..b0841c2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { /* Emit */ "target": "ES2020", - "lib": ["ESNext"], + "lib": ["ES2020"], "declaration": true, // These two options will be selectively overridden in each project. // Utility libraries will have source maps on, but plugins will not. @@ -26,7 +26,7 @@ "noImplicitThis": true, "strictBindCallApply": true, "strictFunctionTypes": true, - "strictNullChecks": true, + "strictNullChecks": false, "strictPropertyInitialization": false, "useUnknownInCatchVariables": true, /* Handled by ESLint */ diff --git a/yarn.lock b/yarn.lock index 7f60f2c..3ecda56 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5426,16 +5426,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -"typescript@>=3 < 6", typescript@^5.2.2: +"typescript@>=3 < 6", typescript@^5.4.5: version "5.4.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.5.tgz#42ccef2c571fdbd0f6718b1d1f5e6e5ef006f611" integrity sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ== -typescript@^4.5.2: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== - uglify-js@^3.1.4: version "3.17.4" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c"