Skip to content

SCENES.md — levels built from asset packs

scenes/*.scene.json are levels made of Synty pack assets. The files name assets and never contain them: the packs are paid, so they stay in the git-ignored assets/synty/ (one folder or symlink per pack) and are found by file name through AssetCatalog. Anyone with the same packs gets the same scene.

  • Format and placement rules: engine/include/kke/SceneFile.h.
  • Loading (render + collision): engine/include/kke/SceneLoader.h.
  • In kke_demo: the Scenes panel has a Go button per scene and "Back to the course". KKE_SCENE=town_block ./kke_demo starts in one. KKE_DEMO_AUTOPILOT=1 sprints from the spawn toward -Z and vaults or climbs whatever is in the way.
  • Building one: the sandbox (games/sandbox, HISTORY.md "Sandbox") saves kke.scene files, by default scenes/sandbox.scene.json, with spawn, sun, ambient, point lights, per-object collision, texture variants and breakable materials. SceneFile::save() writes the same format back (short floats, one line per vector, defaults left out), so saving a loaded scene changes nothing (SceneFile.SavesAndLoadsBackTheSameScene).
  • Tests: SceneTrails.* in tests/test_locomotion.cpp run both trails headless, and the town block again after a save round trip. They skip when the packs are missing (CI).

A game's own models and scenes

A game folder (games/<game>/, made by tools/new_game) can hold its own models/ and scenes/ folders next to scripts/:

  • models/: .glb, .gltf, .fbx or .obj files, in any subfolders. They join the asset catalog as the pack game, searched before the installed packs, so models.load("Fox") and a scene object with "asset": "Fox" find models/Fox.glb. They load with their animation clips, and no pack atlas is guessed for them.
  • scenes/: *.scene.json files. scene.list() and scene.load(name) look here first, then in the shared scenes/ folder.

Both are copied next to the executable with the scripts (the template's CMakeLists.txt), so a shipped game finds them too. While you develop they are read from the game's source folder.

Building a game's level

The sandbox's Build mode is the level editor for any game. Give it the game's folder, and optionally a level name (default level):

./build/bin/sandbox games/my_game          # games/my_game/scenes/level.scene.json
./build/bin/sandbox games/my_game arena    # games/my_game/scenes/arena.scene.json

It opens in Build mode with the game's own models/ in the Assets panel (next to any installed packs) and loads the level if it exists. Place, move, rotate and scale with the gizmo, set the spawn point, mood and lights, then Save (Ctrl+S): the level is written to the game's scenes/ (the folder is made if needed), and the game loads it with scene.load("arena"). See games/sandbox/README.md "Build mode" for the controls.

Getting the packs

tools/fetch_assets.sh downloads packs from the asset share and extracts them into assets/synty/ (--list shows what's there; one zip at a time, deleted after extracting; .unitypackage files are unpacked to their real paths). Example: tools/fetch_assets.sh POLYGON_Town ANIMATION_. It needs KKE_SHARE_HASH (the share's private link hash, never committed).

The startup intro (kke::LogoIntro) uses no packs: its logo is built from assets/branding/kreative-kompas-logo.svg, which is Kreative Kompas's own and committed.

Reproducing a scene

  1. Put the pack in assets/synty/ (or KKE_ASSETS_DIR) under any name: PolygonTown_Source_Files, POLYGON_Town_SourceFiles_v5 and a name of your own all work (docs/ASSETS.md).
  2. Run kke_demo and pick the scene. Missing assets are logged by name and the rest still loads.

Town block (town_block.scene.json)

Pack: POLYGON Town (PolygonTown_Source_Files). 154 instances of 29 assets. A street with a road and a speed bump, three houses and a shop on the north side, a house and deck on the south side, a picket fence with a gate, hedges, a wooden back fence, boxes, barrels, a cart, lamps and trees. Spawn faces the picket fence, which is a vault.

SM_Bld_House_Deck_01, SM_Bld_House_Deck_Rail_01, SM_Bld_House_Preset_02, SM_Bld_House_Preset_03, SM_Bld_House_Preset_05, SM_Bld_Shop_01, SM_Bld_Shop_Concrete_01, SM_Env_Fence_White_Gate_01, SM_Env_Fence_White_Straight_01 ×8, SM_Env_Fence_Wood_Straight_01 ×20, SM_Env_Grass_01 ×80, SM_Env_Grass_Patch_04, SM_Env_Hedge_01, SM_Env_Hedge_03, SM_Env_Path_01 ×10, SM_Env_Road_01 ×10, SM_Env_Road_SpeedBump_01, SM_Env_Tree_01, SM_Env_Tree_02, SM_Env_Tree_03, SM_Env_Tree_Pine_01, SM_Env_Tree_Tall_01, SM_Env_Tree_Tall_02, SM_Prop_Barrel_01 ×2, SM_Prop_CardboardBox_01, SM_Prop_CardboardBox_02, SM_Prop_CardboardBox_03, SM_Prop_Cart_01, SM_Prop_LampStanding_01 ×2

Forest trail (forest_trail.scene.json)

Pack: POLYGON Nature (POLYGON_Nature_Source_Files). 57 instances of 37 assets. A trail along -Z from a camp: a log to step over, a broken pillar, a stone wall, a stump and a fence to vault, a rock shelf to climb, then a curved bridge, ruins and rocks too big to get over. Trees and plants line it; two mountains close the view.

SM_Plant_Bush_01 ×2, SM_Plant_Bush_03 ×2, SM_Plant_Fern_01, SM_Plant_Fern_02 ×2, SM_Plant_Flowers_01, SM_Plant_Mushrooms_01, SM_Prop_Bridge_Curved_01, SM_Prop_CampFire_01, SM_Prop_Chest_Wood_01, SM_Prop_Fence_01 ×3, SM_Prop_Pillar_Arch_Moss_01, SM_Prop_Pillar_Broken_01, SM_Prop_Pillar_Broken_Moss_02, SM_Prop_Pillar_Moss_01, SM_Prop_StoneWall_01, SM_Prop_TorchStick_01 ×2, SM_Rock_Boulder_01, SM_Rock_Cluster_Large_02, SM_Rock_Pile_04, SM_Rock_Rounded_01, SM_Rock_Small_01, SM_Rock_Tile_03, SM_Rock_Wall_01, SM_Terrain_Ground_Mound_Large_01 ×2, SM_Terrain_Mountain_01, SM_Terrain_Mountain_02, SM_Terrain_Rubble_Pebbles_01 ×6, SM_Tree_Birch_01 ×2, SM_Tree_Birch_02 ×2, SM_Tree_Birch_03 ×2, SM_Tree_Log_01, SM_Tree_Pine_01 ×2, SM_Tree_Pine_02 ×2, SM_Tree_Pine_Small_01 ×2, SM_Tree_PolyPine_01 ×2, SM_Tree_Round_02 ×2, SM_Tree_Stump_01

Showcase course art (games/showcase/course_art.scene.json)

Packs: POLYGON Nature and POLYGON Town. 108 instances of 37 assets, placed on kke_demo's course itself (not a separate level), around the stations: a rock heap, dead trees, ash and torches at the lava; reeds, a bench, deckchairs, a lamp and a tree at the pool; barrels, boxes, a cart and a shed at the breaking yard; hedges along the north wall; pines behind the trick wall; pines and mountains beyond the walls, houses, a shop and a church to the south and east. It loads only when every asset is installed (otherwise the course stays plain boxes); KKE_COURSE_ART=0 leaves it out.

POLYGON Nature: SM_Plant_Bush_01 ×2, SM_Plant_Fern_01 ×4, SM_Plant_Flowers_01 ×6, SM_Plant_Grass_03 ×15, SM_Plant_Reeds_01 ×2, SM_Plant_Reeds_02, SM_Prop_TorchStick_01 ×2, SM_Rock_Pile_01, SM_Rock_Pile_Curved_01, SM_Rock_Small_01 ×2, SM_Terrain_DustPile_Long_01, SM_Terrain_DustPile_Small_01, SM_Terrain_Mountain_01, SM_Terrain_Mountain_02, SM_Terrain_Mountain_03, SM_Tree_Birch_01 ×2, SM_Tree_Dead_01, SM_Tree_Dead_02, SM_Tree_Pine_01 ×3, SM_Tree_Pine_Large_01 ×16, SM_Tree_PolyPine_01 ×18, SM_Tree_Round_01

POLYGON Town: SM_Bld_Church_01, SM_Bld_GardenShed_01, SM_Bld_House_Preset_01, SM_Bld_House_Preset_04, SM_Bld_Shop_02, SM_Env_Hedge_01 ×7, SM_Env_Tree_Tall_01 ×2, SM_Prop_Barrel_01 ×2, SM_Prop_CardboardBox_01, SM_Prop_CardboardBox_03, SM_Prop_Cart_01, SM_Prop_Deckchair_01 ×2, SM_Prop_ParkBench_01, SM_Prop_Pool_Float_Ring_01, SM_Prop_Streetlamp_01 ×2

Two assets looked wrong on the engine's loader and were swapped out: SM_Plant_FlowerPatch_01 (flat squares of the atlas) and SM_Tree_Willow_Medium_01 (untextured, grey leaves).

Farm demo (scenes/farm.scene.json)

Used by games/farm_demo (the dog on a farm, AI core). The level was generated by a script and is 60 objects from POLYGON Farm on a 170 × 170 m ground, with the spawn at (0, 0, 8) facing -Z.

  • Buildings: SM_Bld_Barn_01, SM_Bld_Silo_01, SM_Bld_Farmhouse_01.
  • Props: SM_Prop_Windmill_01, SM_Prop_Well_01, SM_Veh_Tractor_01, SM_Prop_Trough_01 ×3, SM_Prop_Hay_Pile_01, SM_Prop_Hay_Bale_Round_01 ×4, SM_Prop_Hay_Bale_Square_01 ×2.
  • Fences: SM_Prop_Fence_Wood_01 ×6 (sheep meadow), SM_Prop_Fence_Wood_Round_01 ×5 (pig pen), SM_Prop_Fence_Wire_01 ×5 (cow pasture).
  • Trees: SM_Env_Tree_Apple_Grown_01 ×2, SM_Env_Tree_Pear_Grown_01, SM_Env_Tree_Large_01, SM_Generic_Tree_01..04 (×3 each), SM_Generic_Tree_Patch_01/02 (×2 each).
  • Horizon: SM_Generic_Mountains_Grass_01 ×8, scaled (2, 1.5, 2).
  • Animals, loaded in code rather than from the scene file:
  • POLYGON Dogs Unity_SK_Animals_Dog_01, keeping only the GermanShepherd_* or Fox_* material parts. Clips from FBX/Animations: Locomotion Standing/Walking/Running; Actions_Standing Eat/Drink/Sniff/Bark/TailWag; Attack Bite; Sleep Idle.
  • Farm Animals Animated by Quaternius (CC0): Sheep (scale 0.23), Cow (0.3), Pig (0.2) and Horse (0.28), with their own clips. Sheep and pigs only have Idle and Jump, so they hop.

Things the packs taught the engine

  • Same names, different packs. POLYGON City and POLYGON Town both have SM_Bld_Shop_01, SM_Env_Road_01, SM_Env_Grass_01 and more, as different models. A scene's "packs" list now decides which one loads (AssetCatalog::find(name, packs)); before that, the town was quietly built from some City models.
  • Mixed units. Some City FBX files say centimeters but hold meters and load 100x too small. loadModel scales an unskinned model from a centimeter file up 100x when it comes out under 10 cm on every axis (ModelLoadOptions::fixUnitMismatch).
  • Textures the FBX doesn't name. Synty meshes are UV-mapped onto the pack atlas even where the material names no texture (Town roofs, fences), so those get the atlas, unless the material has a deliberate colour (blue glass). A few meshes use their own image instead: the road points at an artist's missing .psd but is meant for PolygonTown_Road_01.png, and Nature trees' "Trunk"/"Leave" materials are meant for Birch_Trunk_Texture.png and Leaves_Pine_Texture.png / Leaves_Generic_Texture.png. AssetCatalog::namedTexture finds these by the asset's and the material's names. Leaves are cutout cards, so the model shader now discards transparent texels.
  • Open and flipped meshes. Ray casts hit back faces too, like the character does, so the probe can't see through a wall the capsule can't pass.
  • Seams. A fence is a row of panels. The probe casts from both shoulders as well as the middle, because a centre ray slips through the gap between two panels.
  • Uneven tops. Rocks have bevelled rims and lumpy tops. The probe looks a second time further in when the rim is sloped, and a climb stands on the ground under the target spot, lifted a little if the ground rises under the capsule's rim.
  • Sheets, not solids. SM_Terrain_RiverSide_01 is a surface whose near edge hangs at head height with nothing below it, so it can't be climbed; the trail uses SM_Rock_Tile_03 instead.

Jiggle demo, body scene (games/jiggle_demo)

Not a scene file: the demo loads one body by name and gives it soft-tissue bones in code (kke::addHumanoidSoftTissue: two breast and two glute bones, belly and thigh skin zones).

  • Body: female_body ("Realistic Human Female Body rigged gameready", free on CGTrader; Character Creator 4): Obj/obj.obj and the textures next to it, auto-rigged at load (kke::autoRigHumanoid, no reshaping). Fetch: tools/fetch_assets.sh female_body. KKE_JIGGLE_BODY picks another file.
  • Without it, a character (reshaped: bust +7.5 cm, glutes +6 cm, hips +3 cm): POLYGON Fantasy Characters, SK_Character_Female_Gypsy (falls back to SK_Character_Female_Peasant_01, then POLYGON City Characters SK_Character_HipsterGirl; KKE_JIGGLE_CHARACTER picks any). Texture: the pack's own atlas via packLoadOptions.
  • Clips: Quaternius Universal Animation Library, assets/animations/UAL1_Standard.fbx (Idle_Loop, Walk_Loop, Jog_Fwd_Loop, Sprint_Loop, Jump_Start, Jump_Loop, Jump_Land), retargeted.
  • The jelly scene uses no assets.

Put the pack in assets/synty/POLYGON_Fantasy_Characters/ (a symlink to the shared cache works) or set KKE_ASSETS_DIR.

Duel (games/duel)

No Synty packs. Fighters: Quaternius Universal Animation Library (CC0), the mannequin and clips from assets/animations/UAL1_Standard.fbx (Idle_Loop, Walk_Loop, Punch_Jab, Punch_Cross, Hit_Chest, Hit_Head, Jump_Start, KipUp, Crouch_Idle_Loop, Dance_Loop, Yes: Body.cpp takes the first clip of each list that exists, so most of these are fallbacks for when UAL 2 is missing) and, when present, UAL 2's melee clips (UAL2.fbx: Melee_Hook, Melee_Uppercut, Melee_Knee, Hit_Knockback, LayToIdle, Walk_Fwd/Bwd/L/R_Loop) from assets/animations/ or KKE_ASSETS_DIR/Universal Animation Library 2/Unity/. The ring, gym and benches are boxes built in code.

Goblin Horde (games/goblin_horde)

Not a scene file: the fort, trees and rubble are boxes built in code. Every model is named in data/foes.yml and data/heroes.yml; the first one found is the fallback, then the UAL mannequin.

  • Goblins: POLYGON Goblin War Camp (every goblin is a part of FBX/Characters/Characters.fbx, e.g. SM_Chr_Warrior_Male_01, SM_Chr_Archer_Female_01, SM_Chr_Shaman_01) and POLYGON Dungeon Pack (Character_Goblin_*, Character_Goblin_WarChief). Their weapons, bows, staffs and hats come from both packs.
  • Bosses: POLYGON Fantasy Rivals SK_BR_Character_Troll_01, _Big_Ork_01, _BarbarianGiant_01, _Pig_Butcher_01.
  • Heroes: POLYGON Fantasy Characters (king, queen, rogue, druid, bard, witch, sorcerer, peasant) and the Dungeon Pack knights.
  • Clips: Quaternius UAL 1 (the full UAL1.fbx from the pack, added to the 43-clip UAL1_Standard.fbx the repository ships) and UAL 2 (Sword_Regular_A/B/C, Sword_Heavy_*, Melee_Knee, ...), retargeted by bone name. The War Camp goblins use Synty's older bone names (Shoulder_L, Elbow_L, UpperLeg_L); kke::canonicalBoneName pairs them with UAL's.

Synty demo (games/synty_demo)

Not a scene file: the room is placed in code.

  • Level and props: POLYGON Prototype, SM_Buildings_Floor_5x5_01, SM_Buildings_Wall_5x3_01, SM_Buildings_WallDoor_5x3_01, SM_Buildings_Stairs_1x3_01, SM_Buildings_Column_1x3_01, SM_Prop_Crate_01, SM_Prop_Crate_02, SM_Prop_Crate_Question_01, SM_Prop_Barrel_01, SM_Prop_Barrier_01, SM_Prop_Chest_Wood_01, SM_Prop_Cone_01, SM_Prop_FlagPole_01, SM_Generic_Tree_01 to _03, SM_Generic_Small_Rocks_01, and the pack's grid overlay texture.
  • Characters: POLYGON Prototype, SK_Character_Dummy_Male_01, SK_Character_Dummy_Female_01, SK_Character_Male_Face_01, SK_Character_Female_Face_01.
  • Optional animals: Quaternius Farm Animals (CC0), Horse, Pug.

Without the Prototype pack the demo shows its "pack not found" message.

Pet Companion (games/pet_companion)

Not a scene file: the garden is placed in code, and built from blocks when the packs are missing.

  • POLYGON Town: SM_Env_Fence_Wood_Straight_01, SM_Prop_Doghouse_01, SM_Env_Tree_01, SM_Env_Tree_02, SM_Env_Hedge_01, SM_Prop_Barrel_01, SM_Env_Grass_01, SM_Item_Ball_Soccer_01.
  • The dog: Quaternius Farm Animals (CC0), Pug.
  • The player: the UAL mannequin (assets/animations/UAL1_Standard.fbx).

Platoon (games/platoon)

Not a scene file: the training ground is placed in code, and the cover is built from blocks when the pack is missing.

  • POLYGON Prototype: SM_Prop_Crate_01, SM_Prop_Crate_02, SM_Prop_Crate_03, SM_Prop_Barrier_01.
  • Soldiers on both sides: the UAL mannequin (assets/animations/UAL1_Standard.fbx).

Party (games/party)

Not a scene: the packs only give the start menu's Body row its people; without them everyone is a bean.

  • POLYGON City Characters: SK_Character_Jock, SK_Character_Tourist, SK_Character_FireFighter, SK_Character_Paramedic, SK_Character_Grandpa, SK_Character_Grandma, SK_Character_HipsterGirl, SK_Character_PunkGuy, SK_Character_SummerGirl, SK_Character_Roadworker, SK_Character_Hotdog.
  • Their animation: the UAL mannequin's clips (assets/animations/UAL1_Standard.fbx), retargeted.

Flying (games/flying_demo)

Not a scene file: the island, trees, hangar, tower, office towers, rings, smoke and explosions are built in code from the island's seed.

  • The planes: POLYGON Stunt Plane, SM_Veh_Plane_Stunt_01 (SourceFiles/FBX/), split by mesh name into the body, _Prop, _Flap_fl_01/_02, _Flap_fr_01/_02, _Flap_rl_01, _Flap_rr_01, _Flap_Tail, _Cockpit_Stick, _Glass and _Wheels (_Crop_Duster is left out). Paint jobs: Polygon_Plane_Texture_01 to _04. Without the pack the planes are built from boxes.
  • Dogfight's houses (optional): POLYGON Town, SM_Bld_House_Preset_01 to _11, SM_Bld_Shop_01 to _03 and SM_Bld_Church_01, loaded the first time a dogfight starts. Without the pack the houses are boxes.
  • The Canyon and Mega City maps use no art packs: the plateau, the gorge, its rock pillars and bridges, the city's towers, parks and sky bridges are all built in code from the map's seed.

Racing (games/racing)

Not a scene file: the tracks are built in code from games/racing/tracks/ and the props placed along them, well clear of the road.

  • The cars: POLYGON Street Racer, SK_Veh_Preset_Muscle_01 to _04, SK_Veh_Preset_Sports_01 to _04, SK_Veh_Preset_Exotic_01 to _04, SK_Veh_Preset_Sedan_01 to _04, SK_Veh_Preset_Hatch_01 to _04, SK_Veh_Preset_Ute_01 to _04 (SourceFiles/FBX/Veh/), split into the body and the wheels by mesh name. Paint jobs: PolygonStreetRacer_Veh_Tex_* (Textures/Vehicles/), carbon parts PolygonStreetRacer_Texture_Carbon.
  • Trackside: SM_Prop_Pole_Large_Lights_01, _02, SM_Prop_Sign_Start_01, SM_Prop_Sign_Finish_01, SM_Prop_Barrier_Tyre_StackA_01, SM_Prop_Barrier_Tyre_StackA_02, SM_Prop_Barrier_Tyre_StackB_01, SM_Prop_TyreStack_01, SM_Prop_ToolCabinet_01_Preset, SM_Bld_RepairShop_Large_01 (the oval's pit garage), SM_Bld_Warehouse_01, SM_Bld_Crane_01, SM_Prop_Container_Stack_01, _04, _07, SM_Prop_Container_Large_Stack_02 (the docks), SM_Env_Dirt_Pile_01 to _03, SM_Bld_Shelter_01 (the derby's scrapyard).
  • The rally stage: POLYGON Nature, SM_Tree_Pine_01, SM_Tree_01, _02, _03, SM_Tree_Birch_01, SM_Rock_01 to _03, SM_Rock_Small_01.
  • Without the pack every car is a coloured block of its type's size and the tracks have no props; the log (info) and the start menu say so.

Demos that use no packs

These run the same with or without any asset pack: climb_race, tennis, procedural_demo, physics_demo, melt_demo, sea_demo, audio_demo, rmlui_demo, imgui_demo, starter_game and cookbook. kke_demo dresses its course with the art listed under "Showcase course art" above when the packs are there, and plays the same without them.

Moods

Every demo sets a mood (MOODS.md): the sky, sun, fog, colour look and background sound. The skies are CC0 pictures from Poly Haven, fetched by the build; the sounds are CC0 loops from OpenGameArt in assets/ambience/. Neither is a pack: every demo has them. Try another with KKE_MOOD=<name>.

Demo Mood Sky picture Sound
kke_demo (showcase course) clear_day Kloofendal 48d Partly Cloudy meadow_day
sandbox clear_day Kloofendal 48d Partly Cloudy meadow_day
pet_companion clear_day Kloofendal 48d Partly Cloudy meadow_day
sea_demo clear_day Kloofendal 48d Partly Cloudy meadow_day
audio_demo clear_day Kloofendal 48d Partly Cloudy meadow_day
procedural_demo morning Qwantani Mid Morning meadow_day
farm_demo clear_day Kloofendal 48d Partly Cloudy meadow_day
platoon clear_day Kloofendal 48d Partly Cloudy meadow_day
climb_race each mountain's own (games/climb_race/mountains/): morning, clear_day, golden_hour (Granite Tower, Random), sunset, overcast, misty_morning as the mood as the mood
party each minigame's own: sunset (the lobby and podium), clear_day, dusk, arena_night, noon, golden_hour, playful as the mood as the mood
synty_demo morning Qwantani Mid Morning meadow_day
racing each track's own (games/racing/tracks/): golden_hour (Kompas Speedway), dusk (Harbour Run), noon (The Quarter Mile), sunset (Scrapyard Bowl), morning (Pinewood Stage) as the mood as the mood
flying_demo clear_day; the start menu's Sky row: morning, golden_hour, sunset, stormy as the mood as the mood
goblin_horde sunset Qwantani Sunset wind_soft
tennis clear_day Kloofendal 48d Partly Cloudy meadow_day
duel arena_night Qwantani Night night_crickets
melt_demo dusk Qwantani Dusk 2 night_crickets
starter_game (and every new game), cookbook, jiggle_demo playful gradient none
physics_demo, rmlui_demo, imgui_demo studio gradient none