Skip to content

toddeTV/zlig

Repository files navigation

zlig

project overview

This project represents a japanese style idle game.

Short project name: zlig (stands for zen-landscape-idle-game)

Current deployment on:

dev

commands

  • cleanup
    • sudo rm -rf build dist .output .data
    • sudo rm -rf node_modules

initial setup

VM ID

Development VM ID from Thorsten for this project: 014
(Only interesting to him.)

system requirements for developing

The following softwares are required for development:
(The versions listed were the ones I most recently used for development and testing. So try sticking with them.)

software command for version output my version at last use information
Ubuntu lsb_release -a or cat /etc/os-release 22.04.4 LTS OS
Linux uname -r 5.15.0-119-generic Linux Kernel
VSCode code -v 1.93.2 IDE
nvm nvm -v v0.39.7 Node Version Manager
Node node -v (old nodejs --version) v20.16.0 NodeJS/ Node.js
npm npm -v v10.8.1
npx npx -v v10.8.1
pnpm pnpm -v v9.10.0

In the browser install:

project setup

  1. execute a git pull
  2. open project in VSCode
  3. If you work with VSCode via remote software:
    • {Ctrl}+{Shift}+{P} -> >Preferences: Open Settings (UI) -> search for keyboard.dispatch and set it to keyCode
    • Restart or reload VSCode.
  4. Install recommended extensions/ plugins:
    • Open Extensions menu in VSCode ({Ctrl}+{Shift}+{X})
    • type in the search @recommended
    • install and enable the plugins
    • see file .vscode/extensions.json for configuring some of the extensions
    • Restart or reload VSCode.
  5. In VSCode on the bottom left click your profile image and log in all services (GitHub due to VSCode extensions, ...)
    If the browser to VSCode callback fails, wait for the login popup on the bottom right to timeout (ca. 5 minutes) and then on the upcoming popup question You have not yet finished authorizing [...] Would you like to try a different way? (local server) click Yes and use this alternative login mechanic.
    (When you do not want to wait for the timeout to happen, you can also click the Cancel to trigger the dialog faster.)
  6. Install dependencies: pnpm i
  7. Happy coding <3

namings

  • we use build area and building area (not building lot nor building place).

lint and prettier

This project uses antfu/eslint-config for eslint most of the files. The following extend it:

Keep in mind that the plugin names are renamed, see Plugins Rename, e.g.:

-// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
+// eslint-disable-next-line ts/consistent-type-definitions
type foo = { bar: 2 }

Why I don't use Prettier for every file type

Design

used icon collections

This project uses the following icon collections in descending order, try sticking to them and use from top to bottom. Tipp: Favorite them and use the search over all item collections at once: https://icon-sets.iconify.design/?list=favorite

full name shorthand license note
phosphor ph MIT
Material Design Icons mdi Apache 2.0 (commercial use is allowed, no attribution required)
Material Line Icons line-md MIT animated icons

glTF export with draco compression

Use draco compression in Blender on glTF 2 files:

  1. Create the model in blender
  2. Go to File -> Export -> glTF 2.0 (.glb/.gltf)
  3. In the right side panel
    1. set Format to glTF Seperate (.gltf + .bin + textures)
    2. set Remember Export Settings to true
    3. under Data set Compression to true
    4. under Compression set the compression level between 0-6 (0=less compression; 6=strongest compression)
      I am using 6 most of the time - only when morphing between models, this should be set to 0.

TresJS & ThreeJS

possible import locations

Do not import from three directly but from the direct source instead. Example:

-import { MeshLambertMaterial } from 'three'
+import { MeshLambertMaterial } from 'three/src/materials/MeshLambertMaterial.js'

Seems to work for types, but better use the direct import from the source folder (see above):

<script setup lang="ts">
import type * as THREE from 'three'
</script>
<script setup lang="ts">
import { something } from '@tresjs/cientos'
import { something } from '@tresjs/core'
// import { something } from '@tresjs/nuxt'
// import { something } from '@tresjs/post-processing'
import { something } from 'three'
import { something } from 'three/src/[...].js'
import { something } from 'three-stdlib'
</script>

import and use *.gltf model files

Method 1: With direct useGLTF

<script setup lang="ts">
import useGLTF from '@/composables/useGLTF'

const { scenes } = await useGLTF('/MyModel/MyModel.gltf')
</script>

<template>
  <primitive :object="scenes.someScene" />
</template>
  • All *.gltf models, along with their corresponding *.bin and texture files, are located in /public/. The useGLTF fetches it over HTTP
  • Bc of gltf-files present in the public folder, all gltf files are always bundled in the final app on build, regardless whether they are used or not.
  • no types
  • Direct call of useGLTF, no extra layers or wrappers

Method 2: With generated helper wrappers and type definitions

<script setup lang="ts">
import modelLoader from '@/assets/models/someSubfolder/someModel.gltf'

const { scenes } = await modelLoader
</script>

<template>
  <primitive :object="scenes.someScene" />
</template>
  • All *.gltf models, along with their corresponding *.bin and texture files, are located in /src/assets/models/.

  • To generate helper wrappers and type definitions, run:

    pnpm run generate:gltf-models

    This script scans all model files in the source folder, deconstructs the GLTF JSON representation, and places the generated types in ./node_modules/.tmp/model-types/, ensuring only imported models are included in the final product.

    The script runs automatically:

    • always a .gltf file changes
    • before a dev run
    • before a build
    • after pnpm i
  • Nearly type safe GLTF file representations.
    Importing models is type-safe, and builds will fail if a model is missing.

  • Only the used models are bundled in the final product.

  • On runtime: Runs useGLTF under the hood. So 100% correct objects and usage, no extra layer.
    In dev: Scans the *.gltf file on its own, so the generated typing has redundant code and could be different from what is present on runtime. So be careful when using and test/ double check it!
    Example: In gltfModel.scenes.someScene.traversed.Object the typing only hints real objects and not each primitive that is used to build up the objects. But in runtime these primitives are also present in the traversed.Object - but funnily enough not all ... that is the reason I left away all primitives, just to be sure.

Multiple instances of the same model

For already loaded and parsed models the GLTF loader returns a cached version. So primitive uses then the same model which means the single instance is unmounted and mounted again with other coordinates.

Solution: clone it

<script setup lang="ts">
// ...
const model = scenes.someScene.Object.someObject.clone()
</script>

<template>
  <primitive :object="model" />
</template>

real time shadows

Example shadow configuration below. The so generated shadows currently have heavy artifacts, so we bake the shadows in this project. But here is an example configuration for shadows:

<script setup lang="ts">
import { DirectionalLightShadow } from 'three/src/lights/DirectionalLightShadow.js'

nodes.MyObject.castShadow = true
nodes.MyObject.receiveShadow = true
nodes.MyGroundPlane.receiveShadow = true

const directionalLightShadow = new DirectionalLightShadow()
directionalLightShadow.mapSize.width = 4096
directionalLightShadow.mapSize.height = 4096
directionalLightShadow.normalBias = 0.1
directionalLightShadow.bias = 0.002
</script>

<template>
  <Suspense>
    <TresCanvas shadows>
      <!-- ... -->
      <TresDirectionalLight
        cast-shadow
        :intensity="3.0"
        :position="[4, 8, 4]"
        :shadow="directionalLightShadow"
      />
      <TresAmbientLight :intensity="0.3" />
      <!-- ... -->
    </TresCanvas>
  </Suspense>
</template>

postprocessing

Normally, you could use the packages @tresjs/post-processing and postprocessing in combination for postprocessing TresJS/ ThreeJS. Unfortunately, they are currently not compatible with TresJS core >v4, see comment on issue #16 and issue #32.

Docs and helper websites

prod

Will use the build command out of /package.json.
Building, deploying and hosting is done via Vercel.

Attribution/ Contribution

Project founder & head of project:

Honorable mentions to people that helped this project:

  • Andreas Fehn helped with the project. Thank you <3
  • Moritz Starke helped with general 3D and Blender questions. Thanks mate <3

Respectable mentions to projects that helped this project:

  • [currently none]

Used programs/ softwares, services and dependencies - besides the ones in ./package.json:

  • GitHub Copilot was used in private mode for programming questions.
  • Blender was used as software for creating and editing 3D models.

Used assets/ materials including images and 3D models:

License

Copyright (c) 2024-present, Thorsten Seyschab

This project, including original code and models, is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License (CC BY-NC-SA 4.0). Under this license, others are allowed to remix, adapt, and build upon this work non-commercially, provided they credit the project founder and license any derivative works under the same terms.

Please note that this license applies only to the original content authored by the project’s creators. Third-party libraries, assets, 3D models, and other materials utilized in this project are listed under "Attribution/ Contribution" above and remain the property of their original creators, licensed under their respective terms.

The project founder reserves the right to modify the terms of this license or to offer different licensing arrangements for specific use cases.

For the full license text, please see the LICENSE file.

Need a Different License?

If you are interested in discussing a different licensing arrangement for individual use cases, please feel free to reach out. Custom licensing may be available, but it is not guaranteed.