Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: single file build #181

Open
wants to merge 16 commits into
base: next
Choose a base branch
from
Open

feat: single file build #181

wants to merge 16 commits into from

Conversation

zardoy
Copy link
Owner

@zardoy zardoy commented Aug 18, 2024

No description provided.

Copy link

codesandbox bot commented Aug 18, 2024

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

@zardoy zardoy changed the title One file build feat: one file build Aug 18, 2024
@zardoy
Copy link
Owner Author

zardoy commented Sep 8, 2024

/update

6 similar comments
@zardoy
Copy link
Owner Author

zardoy commented Sep 8, 2024

/update

@zardoy
Copy link
Owner Author

zardoy commented Sep 8, 2024

/update

@zardoy
Copy link
Owner Author

zardoy commented Sep 8, 2024

/update

@zardoy
Copy link
Owner Author

zardoy commented Sep 8, 2024

/update

@zardoy
Copy link
Owner Author

zardoy commented Sep 9, 2024

/update

@zardoy
Copy link
Owner Author

zardoy commented Sep 9, 2024

/update

@zardoy
Copy link
Owner Author

zardoy commented Sep 11, 2024

/update

@zardoy zardoy changed the title feat: one file build feat: single file build Jan 25, 2025
@zardoy
Copy link
Owner Author

zardoy commented Jan 25, 2025

/review

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

File Patching

The code modifies a CSS file by removing font URLs which could break font loading functionality. This modification should be validated to ensure fonts still work correctly in single file build mode.

const patchCssFile = 'node_modules/pixelarticons/fonts/pixelart-icons-font.css'
const text = fs.readFileSync(patchCssFile, 'utf8')
fs.writeFileSync(patchCssFile, text.replaceAll("url('pixelart-icons-font.ttf?t=1711815892278') format('truetype'),", ""), 'utf8')
Data Processing

Complex recipe data processing logic was added that transforms Minecraft recipe data. The transformation logic should be carefully reviewed to ensure it handles all recipe formats correctly.

function processRecipes (current, prev, getData, version) {
  // can require the same multiple times per different versions
  if (current._proccessed) return
  const items = getData('items')
  const blocks = getData('blocks')
  const itemsIdsMap = Object.fromEntries(items.map((b) => [b.id, b.name]))
  const blocksIdsMap = Object.fromEntries(blocks.map((b) => [b.id, b.name]))
  for (const key of Object.keys(current)) {
    const mapId = (id) => {
      if (typeof id !== 'string' && typeof id !== 'number') throw new Error('Incorrect type')
      const mapped = itemsIdsMap[id] ?? blocksIdsMap[id]
      if (!mapped) {
        throw new Error(`No item/block name with id ${id}`)
      }
      return mapped
    }
    const processRecipe = (obj) => {
      // if (!obj) return
      // if (Array.isArray(obj)) {
      //   obj.forEach((id, i) => {
      //     obj[i] = mapId(obj[id])
      //   })
      // } else if (obj && typeof obj === 'object') {
      //   if (!'count metadata id'.split(' ').every(x => x in obj)) {
      //     throw new Error(`process error: Unknown deep object pattern: ${JSON.stringify(obj)}`)
      //   }
      //   obj.id = mapId(obj.id)
      // } else {
      //   throw new Error('unknown type')
      // }
      const parseRecipeItem = (item) => {
        if (typeof item === 'number') return mapId(item)
        if (Array.isArray(item)) return [mapId(item), ...item.slice(1)]
        if (!item) {
          return item
        }
        if ('id' in item) {
          item.id = mapId(item.id)
          return item
        }
        throw new Error('unhandled')
      }
      const maybeProccessShape = (shape) => {
        if (!shape) return
        for (const shapeRow of shape) {
          for (const [i, item] of shapeRow.entries()) {
            shapeRow[i] = parseRecipeItem(item)
          }
        }
      }
      if (obj.result) obj.result = parseRecipeItem(obj.result)
      maybeProccessShape(obj.inShape)
      maybeProccessShape(obj.outShape)
      if (obj.ingredients) {
        for (const [i, ingredient] of obj.ingredients.entries()) {
          obj.ingredients[i] = parseRecipeItem(ingredient)
        }
      }
    }
    try {
      const name = mapId(key)
      for (const [i, recipe] of current[key].entries()) {
        try {
          processRecipe(recipe)
        } catch (err) {
          console.warn(`${version} [warn] Removing incorrect recipe: ${err}`)
          delete current[i]
        }
      }
      current[name] = current[key]
    } catch (err) {
      console.warn(`${version} [warn] Removing incorrect recipe: ${err}`)
    }
    delete current[key]
  }
  current._proccessed = true
}
Resource Loading

New demo world initialization code was added that loads and renders blocks. The block selection and rendering logic should be reviewed for correctness and performance.

const initDemoWorld = async () => {
  const version = '1.21.1'
  preloadAllMcData()
  console.time('load mc-data')
  await loadMinecraftData(version)
  console.timeEnd('load mc-data')
  if (miscUiState.gameLoaded) return
  console.time('load scene')
  const world = getSyncWorld(version)
  const PrismarineBlock = require('prismarine-block')
  const Block = PrismarineBlock(version)
  const fullBlocks = loadedData.blocksArray.filter(block => {
    // if (block.name.includes('leaves')) return false
    if (/* !block.name.includes('wool') &&  */!block.name.includes('stained_glass')/*  && !block.name.includes('terracotta') */) return false
    const b = Block.fromStateId(block.defaultState, 0)
    if (b.shapes?.length !== 1) return false
    const shape = b.shapes[0]
    return shape[0] === 0 && shape[1] === 0 && shape[2] === 0 && shape[3] === 1 && shape[4] === 1 && shape[5] === 1
  })
  const Z = -15
  const sizeX = 100
  const sizeY = 100
  for (let x = -sizeX; x < sizeX; x++) {
    for (let y = -sizeY; y < sizeY; y++) {
      const block = fullBlocks[Math.floor(Math.random() * fullBlocks.length)]
      world.setBlockStateId(new Vec3(x, y, Z), block.defaultState)
    }
  }
  viewer.camera.updateProjectionMatrix()
  viewer.camera.position.set(0.5, sizeY / 2 + 0.5, 0.5)
  viewer.camera.rotation.set(0, 0, 0)
  const initPos = new Vec3(...viewer.camera.position.toArray())
  const worldView = new WorldDataEmitter(world, 2, initPos)
  // worldView.addWaitTime = 0
  await viewer.world.setVersion(version)
  viewer.connect(worldView)
  void worldView.init(initPos)
  await viewer.world.waitForChunksToRender()
  const abortController = new AbortController()
  // add small camera rotation to side on mouse move depending on absolute position of the cursor
  const { camera } = viewer
  const initX = camera.position.x
  const initY = camera.position.y
  let prevTwin: tweenJs.Tween<THREE.Vector3> | undefined
  document.body.addEventListener('pointermove', (e) => {
    if (e.pointerType !== 'mouse') return
    const pos = new THREE.Vector2(e.clientX, e.clientY)
    const SCALE = 0.2
    /* -0.5 - 0.5 */
    const xRel = pos.x / window.innerWidth - 0.5
    const yRel = -(pos.y / window.innerHeight - 0.5)
    prevTwin?.stop()
    const to = {
      x: initX + (xRel * SCALE),
      y: initY + (yRel * SCALE)
    }
    prevTwin = new tweenJs.Tween(camera.position).to(to, 0) // todo use the number depending on diff // todo use the number depending on diff
    // prevTwin.easing(tweenJs.Easing.Exponential.InOut)
    prevTwin.start()
    camera.updateProjectionMatrix()
  }, {
    signal: abortController.signal
  })

  unloadPanoramaCallbacks.push(() => {
    abortController.abort()
  })

  console.timeEnd('load scene')
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant