# Question Block

> A classic 1 m mystery block for platformers: a golden cube with corner rivets and a glowing pixel-art question mark with drop shadow on every side. Switch to a brick block or an empty "used" block, perfect for hiding coins and power-ups on a 1 m grid.

![Question Block preview](https://codels.download/m/question-block.png)

Multi-view sheet (3/4, front, side, top): https://codels.download/m/question-block.sheet.png

## Facts

- Category: Game Kit › Platforms
- Size (W × H × D): 1.07 × 1.02 × 1.07 m — units are meters, +Y up, front faces +Z
- Origin: center of the base (y = 0)
- Triangles: 828 · Meshes: 69 · Materials: 4
- License: CC0-1.0 (Codels built-in)
- Tags: block, blocky, cartoon, low-poly, retro, party-game, platformer, collectible, interactable, modular, platform, brick, gold, boxy-shape, emissive, game-ready, mobile-friendly, parametric, color-brown, color-orange, size-medium, poly-low
- Page: https://codels.download/models/question-block

## Files

| Format | URL |
|---|---|
| three.js ES module (`createQuestionBlock()`) | https://codels.download/m/question-block.js |
| React Three Fiber component (`<QuestionBlock />`) | https://codels.download/m/question-block.jsx |
| Instancing module (`createQuestionBlockInstances(count, place)`, one draw call per material) | https://codels.download/m/question-block.instanced.js |
| Standalone HTML demo | https://codels.download/m/question-block.html |
| glTF binary | https://codels.download/m/question-block.glb |
| glTF binary, Meshopt-compressed (2–3× smaller; GLTFLoader needs `setMeshoptDecoder(MeshoptDecoder)`) | https://codels.download/m/question-block.glb?compress=meshopt |
| glTF JSON | https://codels.download/m/question-block.gltf |
| OBJ (vertex colors) + MTL | https://codels.download/m/question-block.obj · https://codels.download/m/question-block.mtl |
| STL | https://codels.download/m/question-block.stl |
| CodelSpec JSON | https://codels.download/m/question-block.json |

## Parameters

Append them as query parameters to any URL above to get a customized variant (e.g. `?variant=...`).

| Param | Type | Range / options | Default | Current |
|---|---|---|---|---|
| `variant` | select | question \| brick \| used | question | question |
| `color` | color | #rrggbb | #f4a91f | #f4a91f |

## Parts

- block (box · block)
- frontFace (group)
- rightFace (group)
- backFace (group)
- leftFace (group)
- topFace (group)

## How to use

Save the code below as `question-block.js`, then:

```js
import { createQuestionBlock } from './question-block.js';
const model = createQuestionBlock();
scene.add(model);
```

## Code

```js
/**
 * Question Block — Codels 3D model library (https://codels.download/models/question-block)
 * License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
 * Triangles: 828 · Size (W × H × D): 1.07 × 1.02 × 1.07 m
 *
 * Usage:
 *   import { createQuestionBlock } from './question-block.js';
 *   
 *   const model = createQuestionBlock();
 *   model.position.set(0, 0, 0);
 *   scene.add(model);
 */
import * as THREE from 'three';

const deg = THREE.MathUtils.degToRad;

export function createQuestionBlock() {
  const root = new THREE.Group();
  root.name = 'QuestionBlock';

  // Materials
  const blockMat = new THREE.MeshStandardMaterial({ name: 'block', color: 0xf4a91f, roughness: 0.55, flatShading: true });
  const rivetMat = new THREE.MeshStandardMaterial({ name: 'rivet', color: 0x8a4d14, roughness: 0.6, flatShading: true });
  const markMat = new THREE.MeshStandardMaterial({ name: 'mark', color: 0xfff7dc, roughness: 0.5, emissive: 0xffe8a3, emissiveIntensity: 0.55, flatShading: true });
  const markShadowMat = new THREE.MeshStandardMaterial({ name: 'markShadow', color: 0xa3520f, roughness: 0.7, flatShading: true });

  // Shared geometries
  const boxGeo = new THREE.BoxGeometry(0.08, 0.08, 0.04);
  const boxGeo2 = new THREE.BoxGeometry(0.3, 0.1, 0.03);
  const boxGeo3 = new THREE.BoxGeometry(0.3, 0.1, 0.04);
  const boxGeo4 = new THREE.BoxGeometry(0.1, 0.1, 0.03);
  const boxGeo5 = new THREE.BoxGeometry(0.1, 0.1, 0.04);
  const boxGeo6 = new THREE.BoxGeometry(0.1, 0.2, 0.03);
  const boxGeo7 = new THREE.BoxGeometry(0.1, 0.2, 0.04);
  const boxGeo8 = new THREE.BoxGeometry(0.2, 0.1, 0.03);
  const boxGeo9 = new THREE.BoxGeometry(0.2, 0.1, 0.04);

  // Parts
  const block = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), blockMat);
  block.name = 'block';
  block.position.set(0, 0.5, 0);
  root.add(block);
  const frontFace = new THREE.Group();
  frontFace.name = 'frontFace';
  frontFace.position.set(0, 0.5, 0);
  root.add(frontFace);
  const box3 = new THREE.Mesh(boxGeo, rivetMat);
  box3.position.set(-0.38, -0.38, 0.5);
  frontFace.add(box3);
  const box4 = new THREE.Mesh(boxGeo, rivetMat);
  box4.position.set(0.38, -0.38, 0.5);
  frontFace.add(box4);
  const box5 = new THREE.Mesh(boxGeo, rivetMat);
  box5.position.set(0.38, 0.38, 0.5);
  frontFace.add(box5);
  const box6 = new THREE.Mesh(boxGeo, rivetMat);
  box6.position.set(-0.38, 0.38, 0.5);
  frontFace.add(box6);
  const box7 = new THREE.Mesh(boxGeo2, markShadowMat);
  box7.position.set(0.035, 0.265, 0.506);
  frontFace.add(box7);
  const box8 = new THREE.Mesh(boxGeo3, markMat);
  box8.position.set(0, 0.3, 0.515);
  frontFace.add(box8);
  const box9 = new THREE.Mesh(boxGeo4, markShadowMat);
  box9.position.set(-0.165, 0.165, 0.506);
  frontFace.add(box9);
  const box10 = new THREE.Mesh(boxGeo5, markMat);
  box10.position.set(-0.2, 0.2, 0.515);
  frontFace.add(box10);
  const box11 = new THREE.Mesh(boxGeo6, markShadowMat);
  box11.position.set(0.235, 0.115, 0.506);
  frontFace.add(box11);
  const box12 = new THREE.Mesh(boxGeo7, markMat);
  box12.position.set(0.2, 0.15, 0.515);
  frontFace.add(box12);
  const box13 = new THREE.Mesh(boxGeo8, markShadowMat);
  box13.position.set(0.085, -0.035, 0.506);
  frontFace.add(box13);
  const box14 = new THREE.Mesh(boxGeo9, markMat);
  box14.position.set(0.05, 0, 0.515);
  frontFace.add(box14);
  const box15 = new THREE.Mesh(boxGeo4, markShadowMat);
  box15.position.set(0.035, -0.135, 0.506);
  frontFace.add(box15);
  const box16 = new THREE.Mesh(boxGeo5, markMat);
  box16.position.set(0, -0.1, 0.515);
  frontFace.add(box16);
  const box17 = new THREE.Mesh(boxGeo4, markShadowMat);
  box17.position.set(0.035, -0.335, 0.506);
  frontFace.add(box17);
  const box18 = new THREE.Mesh(boxGeo5, markMat);
  box18.position.set(0, -0.3, 0.515);
  frontFace.add(box18);
  const rightFace = new THREE.Group();
  rightFace.name = 'rightFace';
  rightFace.position.set(0, 0.5, 0);
  rightFace.rotation.set(0, deg(90), 0);
  root.add(rightFace);
  const box20 = new THREE.Mesh(boxGeo, rivetMat);
  box20.position.set(-0.38, -0.38, 0.5);
  rightFace.add(box20);
  const box21 = new THREE.Mesh(boxGeo, rivetMat);
  box21.position.set(0.38, -0.38, 0.5);
  rightFace.add(box21);
  const box22 = new THREE.Mesh(boxGeo, rivetMat);
  box22.position.set(0.38, 0.38, 0.5);
  rightFace.add(box22);
  const box23 = new THREE.Mesh(boxGeo, rivetMat);
  box23.position.set(-0.38, 0.38, 0.5);
  rightFace.add(box23);
  const box24 = new THREE.Mesh(boxGeo2, markShadowMat);
  box24.position.set(0.035, 0.265, 0.506);
  rightFace.add(box24);
  const box25 = new THREE.Mesh(boxGeo3, markMat);
  box25.position.set(0, 0.3, 0.515);
  rightFace.add(box25);
  const box26 = new THREE.Mesh(boxGeo4, markShadowMat);
  box26.position.set(-0.165, 0.165, 0.506);
  rightFace.add(box26);
  const box27 = new THREE.Mesh(boxGeo5, markMat);
  box27.position.set(-0.2, 0.2, 0.515);
  rightFace.add(box27);
  const box28 = new THREE.Mesh(boxGeo6, markShadowMat);
  box28.position.set(0.235, 0.115, 0.506);
  rightFace.add(box28);
  const box29 = new THREE.Mesh(boxGeo7, markMat);
  box29.position.set(0.2, 0.15, 0.515);
  rightFace.add(box29);
  const box30 = new THREE.Mesh(boxGeo8, markShadowMat);
  box30.position.set(0.085, -0.035, 0.506);
  rightFace.add(box30);
  const box31 = new THREE.Mesh(boxGeo9, markMat);
  box31.position.set(0.05, 0, 0.515);
  rightFace.add(box31);
  const box32 = new THREE.Mesh(boxGeo4, markShadowMat);
  box32.position.set(0.035, -0.135, 0.506);
  rightFace.add(box32);
  const box33 = new THREE.Mesh(boxGeo5, markMat);
  box33.position.set(0, -0.1, 0.515);
  rightFace.add(box33);
  const box34 = new THREE.Mesh(boxGeo4, markShadowMat);
  box34.position.set(0.035, -0.335, 0.506);
  rightFace.add(box34);
  const box35 = new THREE.Mesh(boxGeo5, markMat);
  box35.position.set(0, -0.3, 0.515);
  rightFace.add(box35);
  const backFace = new THREE.Group();
  backFace.name = 'backFace';
  backFace.position.set(0, 0.5, 0);
  backFace.rotation.set(0, deg(180), 0);
  root.add(backFace);
  const box37 = new THREE.Mesh(boxGeo, rivetMat);
  box37.position.set(-0.38, -0.38, 0.5);
  backFace.add(box37);
  const box38 = new THREE.Mesh(boxGeo, rivetMat);
  box38.position.set(0.38, -0.38, 0.5);
  backFace.add(box38);
  const box39 = new THREE.Mesh(boxGeo, rivetMat);
  box39.position.set(0.38, 0.38, 0.5);
  backFace.add(box39);
  const box40 = new THREE.Mesh(boxGeo, rivetMat);
  box40.position.set(-0.38, 0.38, 0.5);
  backFace.add(box40);
  const box41 = new THREE.Mesh(boxGeo2, markShadowMat);
  box41.position.set(0.035, 0.265, 0.506);
  backFace.add(box41);
  const box42 = new THREE.Mesh(boxGeo3, markMat);
  box42.position.set(0, 0.3, 0.515);
  backFace.add(box42);
  const box43 = new THREE.Mesh(boxGeo4, markShadowMat);
  box43.position.set(-0.165, 0.165, 0.506);
  backFace.add(box43);
  const box44 = new THREE.Mesh(boxGeo5, markMat);
  box44.position.set(-0.2, 0.2, 0.515);
  backFace.add(box44);
  const box45 = new THREE.Mesh(boxGeo6, markShadowMat);
  box45.position.set(0.235, 0.115, 0.506);
  backFace.add(box45);
  const box46 = new THREE.Mesh(boxGeo7, markMat);
  box46.position.set(0.2, 0.15, 0.515);
  backFace.add(box46);
  const box47 = new THREE.Mesh(boxGeo8, markShadowMat);
  box47.position.set(0.085, -0.035, 0.506);
  backFace.add(box47);
  const box48 = new THREE.Mesh(boxGeo9, markMat);
  box48.position.set(0.05, 0, 0.515);
  backFace.add(box48);
  const box49 = new THREE.Mesh(boxGeo4, markShadowMat);
  box49.position.set(0.035, -0.135, 0.506);
  backFace.add(box49);
  const box50 = new THREE.Mesh(boxGeo5, markMat);
  box50.position.set(0, -0.1, 0.515);
  backFace.add(box50);
  const box51 = new THREE.Mesh(boxGeo4, markShadowMat);
  box51.position.set(0.035, -0.335, 0.506);
  backFace.add(box51);
  const box52 = new THREE.Mesh(boxGeo5, markMat);
  box52.position.set(0, -0.3, 0.515);
  backFace.add(box52);
  const leftFace = new THREE.Group();
  leftFace.name = 'leftFace';
  leftFace.position.set(0, 0.5, 0);
  leftFace.rotation.set(0, deg(-90), 0);
  root.add(leftFace);
  const box54 = new THREE.Mesh(boxGeo, rivetMat);
  box54.position.set(-0.38, -0.38, 0.5);
  leftFace.add(box54);
  const box55 = new THREE.Mesh(boxGeo, rivetMat);
  box55.position.set(0.38, -0.38, 0.5);
  leftFace.add(box55);
  const box56 = new THREE.Mesh(boxGeo, rivetMat);
  box56.position.set(0.38, 0.38, 0.5);
  leftFace.add(box56);
  const box57 = new THREE.Mesh(boxGeo, rivetMat);
  box57.position.set(-0.38, 0.38, 0.5);
  leftFace.add(box57);
  const box58 = new THREE.Mesh(boxGeo2, markShadowMat);
  box58.position.set(0.035, 0.265, 0.506);
  leftFace.add(box58);
  const box59 = new THREE.Mesh(boxGeo3, markMat);
  box59.position.set(0, 0.3, 0.515);
  leftFace.add(box59);
  const box60 = new THREE.Mesh(boxGeo4, markShadowMat);
  box60.position.set(-0.165, 0.165, 0.506);
  leftFace.add(box60);
  const box61 = new THREE.Mesh(boxGeo5, markMat);
  box61.position.set(-0.2, 0.2, 0.515);
  leftFace.add(box61);
  const box62 = new THREE.Mesh(boxGeo6, markShadowMat);
  box62.position.set(0.235, 0.115, 0.506);
  leftFace.add(box62);
  const box63 = new THREE.Mesh(boxGeo7, markMat);
  box63.position.set(0.2, 0.15, 0.515);
  leftFace.add(box63);
  const box64 = new THREE.Mesh(boxGeo8, markShadowMat);
  box64.position.set(0.085, -0.035, 0.506);
  leftFace.add(box64);
  const box65 = new THREE.Mesh(boxGeo9, markMat);
  box65.position.set(0.05, 0, 0.515);
  leftFace.add(box65);
  const box66 = new THREE.Mesh(boxGeo4, markShadowMat);
  box66.position.set(0.035, -0.135, 0.506);
  leftFace.add(box66);
  const box67 = new THREE.Mesh(boxGeo5, markMat);
  box67.position.set(0, -0.1, 0.515);
  leftFace.add(box67);
  const box68 = new THREE.Mesh(boxGeo4, markShadowMat);
  box68.position.set(0.035, -0.335, 0.506);
  leftFace.add(box68);
  const box69 = new THREE.Mesh(boxGeo5, markMat);
  box69.position.set(0, -0.3, 0.515);
  leftFace.add(box69);
  const topFace = new THREE.Group();
  topFace.name = 'topFace';
  topFace.position.set(0, 0.5, 0);
  topFace.rotation.set(deg(-90), 0, 0);
  root.add(topFace);
  const box71 = new THREE.Mesh(boxGeo, rivetMat);
  box71.position.set(-0.38, -0.38, 0.5);
  topFace.add(box71);
  const box72 = new THREE.Mesh(boxGeo, rivetMat);
  box72.position.set(0.38, -0.38, 0.5);
  topFace.add(box72);
  const box73 = new THREE.Mesh(boxGeo, rivetMat);
  box73.position.set(0.38, 0.38, 0.5);
  topFace.add(box73);
  const box74 = new THREE.Mesh(boxGeo, rivetMat);
  box74.position.set(-0.38, 0.38, 0.5);
  topFace.add(box74);

  root.traverse((o) => {
    if (o.isMesh) {
      o.castShadow = true;
      o.receiveShadow = true;
    }
  });
  return root;
}

export default createQuestionBlock;
```

---
Codels — 3D models as code for three.js. Search more: https://codels.download/api/v1/models?q=<query> · Guide: https://codels.download/llms.txt
