Props, maps et dupes

Ajouter du contenu sans écrire de code : des modèles 3D à faire apparaître, des cartes jouables et des constructions toutes prêtes.

Identifiants de props

Chaque prop a un identifiant texte, utilisé par ents.SpawnProp, les hooks et les dupes.

FormeExempleOrigine
builtin:<nom>builtin:crateProps intégrés au jeu
addon:<clé>/models/<fichier>addon:local_meubles/models/chaise.glbModèle d'un addon (clé : local_<dossier> ou ws_<id Workshop>)
gadget:<nom>gadget:thrusterGadgets du toolgun (propulseur, roue…), posés avec le toolgun

Props intégrés

IdentifiantNomMasse
builtin:crateCaisse en bois30 kg
builtin:crate_smallPetite caisse8 kg
builtin:plankPlanche10 kg
builtin:beamPoutre40 kg
builtin:palletPalette15 kg
builtin:plate_1x1, plate_2x2, plate_4x4Plaques de métal20 / 60 / 200 kg
builtin:concrete_blockBloc de béton500 kg
builtin:concrete_slabDalle de béton800 kg
builtin:sphere, ball, cylinder, cone, capsule, tireFormes (la balle rebondit)1 à 15 kg
builtin:barrel, barrel_blueBarils25 kg
builtin:traffic_coneCône de signalisation2 kg
builtin:crate_metalCaisse en métal60 kg
builtin:tumbleweedVirevoltant (boule de brindilles qui roule ; sur sb_desert, le vent les pousse)1,5 kg

Pack Construction

Le jeu fournit aussi 31 props texturés pour bâtir (onglet Construction du menu de spawn), aux dimensions métriques rondes pour qu'ils s'alignent. Identifiants addon:base/models/<fichier>, par exemple addon:base/models/concrete_wall_2x2.glb.

FichiersProps
metal_panel_1x1, _2x2, _2x4, _4x4, metal_ramp_2m, metal_grate_2x2Tôles larmées, rampe, caillebotis (ajouré)
metal_ibeam_2m, _4m, metal_tube_square_2m, _4m, metal_angle_2mPoutres en I, tubes carrés (creux), cornière
metal_pipe_2m, metal_pipe_large_3mTuyau Ø 40 cm et buse Ø 2,4 m (creux : on traverse la buse debout)
metal_stairs, metal_railing_2m, metal_frame_cube_1m, _2mEscalier (montée 2 m), garde-corps, cadres
wood_plank_2m, _4m, wood_beam_2m, _4m, wood_plywood, wood_wall_2x2Planches, madriers, contreplaqué, mur en planches
concrete_wall_2x2, _4x2, concrete_slab_4x4, concrete_pillar_3m, concrete_stairs, concrete_barrier, concrete_blockMurs, dalle, poteau, escalier, séparateur, parpaing
glass_window_1x1.5Fenêtre (cadre et vitre)

Les objets creux sont faits de pièces convexes séparées (une collision par pièce) : on passe dans un tube, on monte un escalier. Ils sont générés avec Blender par tools/blender/construction_pack.py, qui sert aussi d'exemple pour créer un pack par script.

Créer un prop

Le plus simple est l'éditeur de modèles (Créer → Modèles) : il importe les fichiers glTF, GLB et FBX, et règle la taille, la physique, les collisions, les matériaux et les animations, avec un aperçu.

Pour préparer le modèle dans Blender :

  1. Modélise l'objet à l'échelle réelle, en mètres, avec l'origine au centre de l'objet (l'éditeur permet aussi de corriger l'échelle et le pivot).
  2. Exporte en glTF binaire (.glb) avec les matériaux. Les textures doivent être des images (les nœuds procéduraux ne s'exportent pas).

Tu peux aussi déposer directement le .glb dans le dossier models/ d'un addon : il apparaît dans le menu de spawn avec les réglages par défaut.

Collisions et masse

props.json

Les réglages de chaque modèle sont dans models/props.json. L'éditeur de modèles l'écrit pour toi ; son format complet est décrit dans Le fichier props.json. Version minimale :

{
	"chaise.glb": { "name": "Chaise de bureau", "mass": 12 },
	"armoire.glb": { "name": "Grande armoire", "mass": 90 }
}
MultijoueurSi un joueur n'a pas le modèle (addon local de l'hôte, non publié), il voit un cube rouge ERROR à la place, comme dans GMod. Le vrai modèle remplace le cube dès que l'addon est installé.

Cartes intégrées

Le jeu fournit trois cartes, choisies dans Jouer → Créer une partie ou par leur identifiant (server.cfg, /map, rotation des maps) :

IdentifiantCarte
builtin:sb_natureboxPlaine herbeuse entourée de collines, avec un bâtiment, une piscine et des rampes. Carte par défaut (l'ancien identifiant builtin:gm_construct la charge aussi).
builtin:sb_desertCanyon western en fin d'après-midi : la ville de Red Rock (shérif, banque, saloon, hôtel, magasin, barbier, église, écurie, tous visitables), la gare et son train, une voie ferrée jusqu'à une mine abandonnée (tunnel, chevalement, wagonnets), une rivière avec un pont et un gué, une piste pour les véhicules avec un tremplin, une arche naturelle, des cheminées de fée, des cactus et des virevoltants poussés par le vent.
builtin:sb_createÉtendue plate de terre sous un ciel bleu nuageux, sans aucun décor : rien que du sol pour construire. On y circule sur 2 × 2 km (des murs invisibles en marquent le bord) ; les PNJ trouvent leur chemin sur le kilomètre carré central et marchent tout droit au-delà.

Créer une map

Les maps se construisent dans le jeu avec l'éditeur de map (Créer → Maps → Nouvelle map) : blocs, props, lumières, eau, points d'apparition et ciel, seul ou à plusieurs. Elles sont enregistrées en .pcmap dans le dossier maps/ d'un addon, et apparaissent dans Jouer → Créer une partie et Explorer → Cartes.

Maps et serveursLe serveur envoie la map aux joueurs qui le rejoignent : elle n'a pas besoin d'être installée chez eux. Les props d'addons qu'elle contient, eux, doivent être installés (sinon cube ERROR) : publie les addons utilisés.

Importer une map Source (.bsp)

L'outil tools/bsp_to_physicore.py (dans le dossier du projet) convertit une map de Garry's Mod, Counter-Strike: Source ou Half-Life 2 en addon local : un .pcmap qui s'ouvre dans l'éditeur de map et se lance comme les autres.

pip install srctools Pillow numpy
python tools/bsp_to_physicore.py C:/Maps/rp_downtown_v2/maps/rp_downtown_v2.bsp

Les textures et modèles absents du .bsp sont lus dans les VPK de Garry's Mod (contenu HL2 et CS:S compris) : il faut Garry's Mod installé (--gmod pour un autre dossier, --content pour un dossier materials/ models/ en plus). L'addon est écrit dans le dossier des addons de PhysiCore (--out pour un autre).

Dans la map SourceDans PhysiCore
Brushes du monde, displacements, brushes fixes (func_brush, vitres func_breakable_surf…)Morceaux de 26 m environ (world_*.glb), posés en objets Décor (collision exacte). Les surfaces outils (nodraw, clip, trigger, ciel) et la skybox 3D sont retirées.
Textures VTF, normal maps, transparence, matériaux auto-éclairésImages .webp dans textures/ et réglages de props.json
LightmapsUne image par morceau (lightmaps/), champ lightmap des matériaux
prop_static, prop_dynamicUn .glb par modèle MDL, posé en Décor
prop_physicsProps physiques de la map
info_player_start (et ceux des équipes)Points d'apparition
light, light_spot, light_environmentLumières (sans ombres, 60 m d'affichage) et soleil de l'environnement
EauVolumes d'eau (une boîte par nappe, 3 m de fond)
prop_door_rotating, func_door, func_door_rotatingEntités scriptées sdoor_<modèle> : la porte s'ouvre et se ferme avec E
func_buttonEntités sbutton_<modèle> : E envoie ses sorties (OnPressed…) aux entités nommées

Les modèles de la map sont rangés dans models/<map>/ (un sous-dossier) : ils n'apparaissent pas dans le menu de spawn. Les autres entités (logique, trains, sons, décalcomanies…) ne sont pas converties.

Portes et boutons

Les classes sdoor et sbutton sont écrites dans lua/entities/ de l'addon ; chaque modèle a sa petite classe qui en hérite (ENT.Base, ENT.Model). Leurs propriétés se modifient dans l'éditeur de map (onglet Entités) :

PropriétéRôle
moderotate (pivote autour de son origine) ou slide (glisse)
dist, speedDegrés et degrés/s, ou mètres et m/s
axis, dirAxe de rotation (z = vertical) ou direction de glissement « x y z »
opendir0 : s'ouvre en s'écartant du joueur ; 1 / 2 : toujours dans le même sens
waitSecondes avant de se refermer seule (-1 = jamais)
locked, startopen1 = verrouillée, ouverte au départ
outputs (bouton)Sortie>cible>Entrée séparés par ;, par exemple OnPressed>porte_1>Toggle

Entrées reconnues par les portes : Open, Close, Toggle, Lock, Unlock ; par les boutons : Press. En Lua (serveur) : SourceIO.Fire("porte_1", "Open", ply). Pendant son mouvement, une porte laisse passer les joueurs (COLLISION_GROUP_PASSABLE_DOOR).

Options

OptionEffet
--title, --folderTitre de l'addon et de la map, nom du dossier
--max-texture 512Textures plus petites (1024 px par défaut)
--no-normals, --no-lightmaps, --no-lightsSans normal maps, sans lightmaps, sans lumières Godot
--lightmap-scale, --lightmap-gammaPlus sombre (> 1) ou plus clair (< 1) ; courbe des ombres (1 = fidèle à Source, 0,55 par défaut)
DroitsUne map Source, ses textures et ses modèles appartiennent à leurs auteurs et à Valve. Convertir pour jouer chez soi est une chose ; ne republie pas une map convertie sur le Workshop sans l'accord de son auteur.

Importer une map Unreal Engine

Le plugin PhysiCore Exporter (dossier tools/unreal/PhysiCoreExporter du projet, écrit en Python, sans compilation) convertit le niveau ouvert dans Unreal Engine 5 en addon local : un pack de modèles (un .glb par mesh, dans le menu de spawn) et une map .pcmap qui place ces modèles.

Installation

  1. Copie le dossier PhysiCoreExporter dans le dossier Plugins/ de ton projet Unreal (crée-le s'il n'existe pas).
  2. Ouvre le projet : le plugin active tout seul Python Editor Script Plugin, Editor Scripting Utilities et Procedural Mesh Component (Unreal peut demander de redémarrer).
  3. Ouvre le niveau à convertir, puis menu Outils → PhysiCore → Exporter vers PhysiCore…
  4. Choisis le dossier de sortie (en général %APPDATA%\Godot\app_userdata\PhysiCore\addons) et valide. Relance PhysiCore : l'addon apparaît, sa map s'ouvre dans l'éditeur de map ou se lance comme les autres.
Dans UnrealDans PhysiCore
Static Mesh (acteurs, composants des Blueprints, instances ISM / HISM / foliage)Un modèle models/<mesh>.glb par mesh, posé en objets Décor (collision exacte calculée par le jeu). Une échelle d'acteur différente donne une variante (<mesh>_v2.glb…), 24 au plus par mesh
MatériauxRéglages de props.json : texture couleur, normal map (vert inversé pour Godot), rugosité et métal (valeur, ou texture sur le canal rouge), émission, couleur unie, Masked → découpe, Translucent → transparent. Textures en .png dans models/textures/
Nanite, meshes très détaillésLe LOD le plus détaillé sous la limite de triangles (le mesh de secours pour Nanite)
PlayerStartPoints d'apparition (un à l'origine s'il n'y en a pas)
Point Light, Spot Light, Rect LightLumières et spots (couleur, intensité, portée, angle ; ombres seulement s'il y a 32 lumières ou moins, 80 m d'affichage)
Directional LightSoleil de l'environnement (direction, couleur, intensité ; la plus forte si plusieurs)

Ne sont pas convertis : Landscape, Blueprints (leur logique), Niagara, décalcomanies, ciel et brouillard, éclairage Lumen ou précalculé, graphes de matériaux complexes (seules les textures branchées sont reprises). Avec World Partition, seules les cellules chargées dans l'éditeur sont exportées. Une map garde au plus 20 000 objets, à moins de 10 km de l'origine.

Réglages

RéglageEffet
Dossier de sortie, nom du dossier de l'addon, titreL'addon est écrit dans <sortie>/<dossier>/ (nom du niveau par défaut) ; les modèles ont l'id addon:local_<dossier>/models/<fichier>.glb
Seulement les acteurs sélectionnésExporte la sélection du niveau au lieu de tout le niveau
LumièresDécoché : pas de lumières (le soleil est toujours repris)
Triangles max par mesh60 000 par défaut
Taille max des textures2048 px par défaut (réduites par moitiés)

Les réglages sont gardés dans Saved/PhysiCoreExporter.json du projet Unreal. Réexporter remplace les modèles, les textures et la map, garde addon.json et les réglages de props.json des modèles qui ne sont plus exportés. Les retouches faites dans l'éditeur de modèles sur un modèle réexporté sont perdues. Le résumé de l'export s'affiche à la fin, et le détail est dans le journal de sortie d'Unreal (lignes [PhysiCore]).

Exporter tout un dossier de contenu (sans niveau)

Pour convertir tous les meshes d'un pack (et pas seulement ceux placés dans un niveau), le dossier tools/unreal/ contient un export en ligne de commande. Le projet peut rester ouvert dans Unreal :

  1. export_asset_pack.py, lancé par UnrealEditor-Cmd.exe Projet.uproject -run=pythonscript -script=… avec -nullrhi : variables PC_PACK (dossier, ex. /Game/ModernCityEnvironment01), PC_OUT (dossier de l'addon), PC_STAGE (dossier de travail) et PC_KIND (StaticMesh, puis SkeletalMesh). Chaque Static Mesh devient un .glb à l'échelle 1 (LOD 0, ou le LOD le plus détaillé sous 60 000 triangles) ; les Skeletal Meshes sont exportés en glTF dans leur pose de repos ; les textures sont sorties à leur résolution d'origine ;
  2. finish_asset_pack.py (Python avec Pillow) : convertit les Skeletal Meshes en modèles statiques via Blender, les textures en JPEG (PNG si transparence, normal maps en PNG avec le vert inversé, textures ORM séparées en rugosité et métal), applique les teintes des instances de matériaux et écrit props.json d'après un fichier de règles (nom traduit, catégorie, physique, modèles cachés du menu de spawn) — exemple : moderncity_config.json.

Les modèles sont gelés au spawn avec une masse estimée d'après leur taille ; le jeu calcule lui-même des LOD simplifiés au chargement.

Options utiles : PC_INCLUDE (expression régulière sur le chemin des assets, pour ne garder que certains dossiers) ; PC_PARAM_MATERIALS=1 pour les packs dont les matériaux maîtres sont trop complexes : les textures sont alors prises d'après les noms de paramètres des instances et de leurs parents (BaseColor, Normal, ORM/ORMH, Tint, Brightness) ; dans le fichier de règles, "max_texture": 2048 plafonne la taille des textures.

Pour les packs dont les immeubles sont assemblés dans les niveaux (pièces modulaires posées par des Blueprints), export_buildings.py fusionne chaque immeuble en un seul modèle : variable PC_LEVELS (niveaux séparés par des virgules) et PC_GROUP (expression sur le dossier des acteurs dans l'Outliner, défaut ^Buildings/([^/]+)). Pivot au centre de la base, un matériau par surface, un immeuble identique dans deux niveaux n'est écrit qu'une fois. Ajoute "extra_manifests": ["manifest_buildings.json"] au fichier de règles pour que finish_asset_pack.py les inclue.

Pour refaire ensuite un niveau du pack avec ces modèles, export_level_to_pack.py (même commande, variable PC_LEVEL, ex. /Game/ModernCityEnvironment01/Maps/ModernCityMap01) écrit maps/<niveau>.pcmap dans l'addon : chaque mesh placé à l'échelle 1 avec ses matériaux d'origine reprend le modèle du pack ; un mesh mis à l'échelle, aux matériaux remplacés ou hors du pack devient une variante lvl_<nom>_<n>.glb, cachée du menu de spawn par finish_asset_pack.py (à relancer après). Les Skeletal Meshes placés à l'échelle 1 reprennent leur modèle figé, et les lumières sont exportées en lumières statiques : calcule l'éclairage de la map dans l'éditeur (Monde → Éclairage) pour qu'elles passent au système de lumières économique.

DroitsLes assets du Marketplace / Fab ont une licence limitée à Unreal Engine pour la plupart : vérifie-la avant de publier une map convertie sur le Workshop.

Importer une scène Unity

Le package PhysiCore Exporter pour Unity 6 (dossier tools/unity/PhysiCoreExporter du projet, en C#) convertit la scène ouverte en addon local, au même format que l'export Unreal : un modèle .glb par maillage (dans le menu de spawn) et une map .pcmap qui les place.

  1. Copie le dossier PhysiCoreExporter dans Assets/ du projet Unity, ou installe-le avec Package Manager → + → Install package from disk… (fichier package.json).
  2. Ouvre la scène, puis menu Tools → PhysiCore → Exporter la scène…
  3. Règle l'export, clique Exporter… et choisis le dossier de l'addon (la fenêtre part de %APPDATA%\Godot\app_userdata\PhysiCore\addons). Relance PhysiCore : la map est dans la liste et s'ouvre dans l'éditeur de map.
Dans UnityDans PhysiCore
MeshRenderer (SkinnedMeshRenderer : figé dans sa pose actuelle)Un modèle models/<maillage>.glb par maillage, posé en objets Décor (collision exacte). Une échelle différente donne une variante (<maillage>_2.glb…), 24 au plus par maillage. Seul le LOD 0 des LOD Group est pris
Matériaux (tous shaders : Lit, Shader Graph, Amplify…)Précalculés : le maillage est déplié à plat et rendu avec son propre matériau sous une lumière ambiante blanche, ce qui donne sa couleur telle que le shader la calcule (mélanges de textures, mousse, occlusion), intégrée au .glb. Le feuillage découpé est détecté (transparence Découpe dans props.json). Normal map du matériau. Maillages aux UV répétées (murs, sols) et matériaux transparents : texture principale, teinte et répétition du matériau
NetworkStartPosition, objets vides nommés Spawn / PlayerStartPoints d'apparition (un à l'origine s'il n'y en a pas)
Point Light, Spot LightLumières et spots (couleur, intensité, portée, angle ; ombres seulement s'il y a 32 lumières ou moins)
Directional LightSoleil de l'environnement (la plus forte si plusieurs)

Ne sont pas convertis : terrains Unity, végétation peinte sur les terrains, particules, scripts, sons, ciel et brouillard. Les surfaces métalliques précalculées sortent un peu plus sombres ; un shader qui déplace ses sommets (vent) ou dépend de la position dans le monde (triplanar) peut mal se précalculer : décoche alors Précalculer les matériaux. Réexporter dans le même dossier remplace les modèles et la map, et garde addon.json et les autres entrées de props.json. Le résumé s'affiche à la fin et dans la console d'Unity.

DroitsLes assets de l'Asset Store peuvent s'utiliser dans un jeu, mais pas se redistribuer tels quels : publier sur le Workshop une map faite de modèles de l'Asset Store peut enfreindre leur licence.

Les dupes

Une dupe est une construction sauvegardée : des props, leurs positions, et depuis la version 2, leurs contraintes (soudures, axes, cordes…) et leurs gadgets (propulseurs, roues avec leurs touches et réglages). Une voiture dupliquée repart donc entièrement fonctionnelle.

Créer et utiliser une dupe

  1. Prends le toolgun (2) et choisis l'outil Duplicateur dans le menu de spawn.
  2. Clic gauche sur les props à inclure (ils s'éclairent en cyan), puis clic droit pour sauvegarder en lui donnant un nom.
  3. Pour la recoller : menu de spawn → onglet Dupes → clique sur la dupe. Elle apparaît là où tu vises, orientée selon ton regard.

Les dupes sauvegardées sont dans %APPDATA%\Godot\app_userdata\PhysiCore\dupes\. Pour en partager une dans un addon, place son fichier dans le dossier dupes/ de l'addon (ou utilise Publier, qui le fait pour toi).

Format d'une dupe

Un fichier JSON. Les positions sont relatives à l'origine de la dupe (centre au sol de la construction, orienté comme le joueur au moment de la sauvegarde). Les valeurs Godot (vecteurs, couleurs dans data) sont écrites en texte au format Godot.

{
	"name": "Ma voiture",
	"version": 2,
	"props": [
		{
			"id": "builtin:plate_2x2",
			"pos": [0.0, 0.55, 0.0],
			"rot": [0.0, 0.0, 0.0, 1.0],
			"frozen": false,
			"color": "ffffffff",
			"data": "{}"
		},
		{
			"id": "gadget:wheel",
			"pos": [1.1, 0.45, 0.8],
			"rot": [0.0, 0.0, -0.7071, 0.7071],
			"frozen": false,
			"color": "ffffffff",
			"data": "{\"key_back\": 4194440, \"key_fwd\": 4194446, \"radius\": 0.45, \"speed\": 18.0, \"torque\": 800.0}"
		}
	],
	"constraints": [
		{
			"type": "axis",
			"a": 1,
			"b": 0,
			"la": "Vector3(0, 0, 0)",
			"lb": "Vector3(1.1, -0.1, 0.8)",
			"axis": "Vector3(0, 1, 0)",
			"params": "{\"motor\": true, \"torque\": 800.0}"
		}
	]
}
ChampDescription
props[].idIdentifiant du prop ou du gadget
props[].pos / rotPosition (m) et rotation (quaternion x, y, z, w), relatives à l'origine
props[].frozen, colorFigé ou non ; teinte en hexadécimal RRGGBBAA
props[].dataRéglages du prop : gadgets (force, touches du pavé numérique, rayon…), matériau, masse
constraints[].typeweld, nocollide, rope, elastic, axis, ballsocket, winch, slider, keepupright
constraints[].a / bIndex des props dans la liste props (b = -1 : attaché au monde)
la / lbPoints d'attache locaux sur a et b (pour le monde : position relative à l'origine)
axis, paramsAxe local (axes, glissières) ; paramètres (longueur de corde, raideur, moteur…)

Les dupes de la version 1 (sans data ni constraints) restent lisibles.

Ce que garde le serveurUne dupe vient d'un joueur : le serveur ne garde de data que les réglages d'un gadget (bornés comme dans le toolgun) avec son état allumé / éteint, et le matériau et la masse d'un prop ; de params, que les paramètres du type de contrainte (bornés eux aussi). Le reste (autres données posées par des scripts Lua, armes au sol…) est ignoré, sauf ce que le Lua du serveur accepte : les entités scriptées sont recréées par leur classe (duplicator.RegisterEntityClass, ou duplication générique sans ENT.DisableDuplicator), et les modificateurs d'entité (duplicator.StoreEntityModifier, 8 Ko au plus par prop) sont réappliqués par leur fonction. Le hook CanDuplicate peut refuser une dupe. Les props et points d'attache à plus de 150 m de l'origine sont refusés. Les valeurs texte ne peuvent contenir que des données (vecteurs, couleurs…), jamais Object(…) ni Resource(…) : une telle valeur est ignorée.

Limites

LimiteValeur
Props par joueur200
Distance maximale pour faire apparaître un prop ou une dupe60 m autour du joueur
Props par dupe150
Contraintes par dupe300

Les props d'une dupe dont l'addon manque sont ignorés ; le joueur est prévenu du nombre de props non créés.