@jgengine/shell
v0.18.0
Published
Game player shell for JGengine: React Three Fiber canvas, orbit camera, input tracking, HUD mounting, GameUiPreview, and a demo game. Consumers supply a GameRegistry.
Downloads
2,106
Readme
@jgengine/shell
Game player shell for JGengine: a React Three Fiber canvas with orbit camera + follow feel, input tracking, hotbar/primary-click plumbing, HUD mounting, an error overlay, GameUiPreview for staged HUD screenshots, and a demo game. You supply a GameRegistry mapping game ids to lazy PlayableGame loaders:
import { GamePlayerShell } from "@jgengine/shell/GamePlayerShell";
import type { GameRegistry } from "@jgengine/shell/registry";
const games: GameRegistry = {
"my-game": () => import("./game").then((m) => m.myGame),
};
<GamePlayerShell playable={await games["my-game"]()} />;Peer deps: react, three, @react-three/fiber, @react-three/drei, three-stdlib. The shell's HUD classes are Tailwind — add an @source entry for node_modules/@jgengine/shell in your CSS. Apache-2.0.
Weather primitives are available from @jgengine/shell/weather for game scene overlays:
import { WeatherLayer, LightningStrike } from "@jgengine/shell/weather";
<WeatherLayer mode="rain" intensity={0.8} wind={[1.5, 0, -0.4]} rain={{ count: 7000 }} />;
<LightningStrike origin={[0, 22, 0]} target={[4, 0, -6]} strikeKey={stormTick} />;RainField and SnowField can also be mounted directly. The primitives use camera-following instanced volumes, prop-driven density controls, shared time/wind uniforms under WeatherLayer, and explicit Three resource disposal. They were shaped from ideas in achrefelouafi's MIT RainSystemThreeJS and SnowSystemThreeJS references (see CREDITS.md) without bringing over GUI, audio, postprocessing, or app-specific scene setup.
Water
@jgengine/shell/water renders the Gerstner ocean surface from @jgengine/core:
import { Ocean } from "@jgengine/shell/water";
<Ocean />;Summed Gerstner waves, crest-driven foam, and Fresnel water color were shaped from achrefelouafi's MIT OceanThreejs reference (see CREDITS.md).
Structures
GeneratedBuilding renders the seeded facade/roof kit produced by generateBuilding in @jgengine/core:
import { GeneratedBuilding } from "@jgengine/shell/structures/GeneratedBuilding";
import { generateBuilding } from "@jgengine/core/world/buildings";
<GeneratedBuilding building={generateBuilding({ seed: "block-a", floors: 6 })} />;Building parts are batched into one InstancedMesh per part kind, so a whole building costs about a dozen draw calls regardless of part count. InstancedBuildings batches many buildings together the same way — a full district in one pass — and is what EnvironmentScene uses for building() world features:
import { InstancedBuildings } from "@jgengine/shell/structures/GeneratedBuilding";
import { generateBuildingDistrict } from "@jgengine/core/world/buildings";
const district = generateBuildingDistrict({ rows: 3, cols: 3, seed: "downtown" });
<InstancedBuildings buildings={district.map((building) => ({ building }))} />;The component vocabulary (windows, awnings, AC units, clotheslines, storefronts, shutters, store signs, roof props, guardrails) and placement logic follow achrefelouafi's MIT BuildingGeneratorThreeJS (see CREDITS.md).
Terrain primitives
@jgengine/shell/terrain exports R3F helpers for shell-local natural scenes:
import { GrassField, ProceduralGround, createProceduralTerrainSampler } from "@jgengine/shell/terrain";
const terrain = { seed: "meadow", size: 48, height: 0.9 };
const heightAt = createProceduralTerrainSampler(terrain);
<>
<ProceduralGround terrain={terrain} />
<GrassField area={48} heightAt={heightAt} density={0.65} />
</>;