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.
| Forme | Exemple | Origine |
|---|---|---|
builtin:<nom> | builtin:crate | Props intégrés au jeu |
addon:<clé>/models/<fichier> | addon:local_meubles/models/chaise.glb | Modèle d'un addon (clé : local_<dossier> ou ws_<id Workshop>) |
gadget:<nom> | gadget:thruster | Gadgets du toolgun (propulseur, roue…), posés avec le toolgun |
Props intégrés
| Identifiant | Nom | Masse |
|---|---|---|
builtin:crate | Caisse en bois | 30 kg |
builtin:crate_small | Petite caisse | 8 kg |
builtin:plank | Planche | 10 kg |
builtin:beam | Poutre | 40 kg |
builtin:pallet | Palette | 15 kg |
builtin:plate_1x1, plate_2x2, plate_4x4 | Plaques de métal | 20 / 60 / 200 kg |
builtin:concrete_block | Bloc de béton | 500 kg |
builtin:concrete_slab | Dalle de béton | 800 kg |
builtin:sphere, ball, cylinder, cone, capsule, tire | Formes (la balle rebondit) | 1 à 15 kg |
builtin:barrel, barrel_blue | Barils | 25 kg |
builtin:traffic_cone | Cône de signalisation | 2 kg |
builtin:crate_metal | Caisse en métal | 60 kg |
builtin:tumbleweed | Virevoltant (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.
| Fichiers | Props |
|---|---|
metal_panel_1x1, _2x2, _2x4, _4x4, metal_ramp_2m, metal_grate_2x2 | Tôles larmées, rampe, caillebotis (ajouré) |
metal_ibeam_2m, _4m, metal_tube_square_2m, _4m, metal_angle_2m | Poutres en I, tubes carrés (creux), cornière |
metal_pipe_2m, metal_pipe_large_3m | Tuyau Ø 40 cm et buse Ø 2,4 m (creux : on traverse la buse debout) |
metal_stairs, metal_railing_2m, metal_frame_cube_1m, _2m | Escalier (montée 2 m), garde-corps, cadres |
wood_plank_2m, _4m, wood_beam_2m, _4m, wood_plywood, wood_wall_2x2 | Planches, madriers, contreplaqué, mur en planches |
concrete_wall_2x2, _4x2, concrete_slab_4x4, concrete_pillar_3m, concrete_stairs, concrete_barrier, concrete_block | Murs, dalle, poteau, escalier, séparateur, parpaing |
glass_window_1x1.5 | Fenê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 :
- 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).
- 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
- Par défaut, la collision est une enveloppe convexe par maillage. Pour un objet creux (une tasse, une arche), place des formes simples dans l'éditeur de modèles.
- Sans masse indiquée, elle est estimée d'après la taille de l'objet et la densité de son matériau physique.
- Les props flottent si leur densité est inférieure à celle de l'eau (1000 kg/m³) : le bois flotte, le métal coule.
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 }
}
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) :
| Identifiant | Carte |
|---|---|
builtin:sb_naturebox | Plaine 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_desert | Canyon 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.
- L'identifiant d'une map suit la même règle que les props :
addon:<clé>/maps/<fichier>.pcmap. - Les props posés dans une map deviennent de vrais props physiques au lancement de la partie (créés par le serveur, sans propriétaire).
- Les anciennes maps
.glbne sont plus chargées : un .pcmap ne contient que des données, ce qui empêche une map du Workshop d'exécuter du code.
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 Source | Dans 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és | Images .webp dans textures/ et réglages de props.json |
| Lightmaps | Une image par morceau (lightmaps/), champ lightmap des matériaux |
prop_static, prop_dynamic | Un .glb par modèle MDL, posé en Décor |
prop_physics | Props physiques de la map |
info_player_start (et ceux des équipes) | Points d'apparition |
light, light_spot, light_environment | Lumières (sans ombres, 60 m d'affichage) et soleil de l'environnement |
| Eau | Volumes d'eau (une boîte par nappe, 3 m de fond) |
prop_door_rotating, func_door, func_door_rotating | Entités scriptées sdoor_<modèle> : la porte s'ouvre et se ferme avec E |
func_button | Entité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 |
|---|---|
mode | rotate (pivote autour de son origine) ou slide (glisse) |
dist, speed | Degrés et degrés/s, ou mètres et m/s |
axis, dir | Axe de rotation (z = vertical) ou direction de glissement « x y z » |
opendir | 0 : s'ouvre en s'écartant du joueur ; 1 / 2 : toujours dans le même sens |
wait | Secondes avant de se refermer seule (-1 = jamais) |
locked, startopen | 1 = 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
| Option | Effet |
|---|---|
--title, --folder | Titre de l'addon et de la map, nom du dossier |
--max-texture 512 | Textures plus petites (1024 px par défaut) |
--no-normals, --no-lightmaps, --no-lights | Sans normal maps, sans lightmaps, sans lumières Godot |
--lightmap-scale, --lightmap-gamma | Plus sombre (> 1) ou plus clair (< 1) ; courbe des ombres (1 = fidèle à Source, 0,55 par défaut) |
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
- Copie le dossier
PhysiCoreExporterdans le dossierPlugins/de ton projet Unreal (crée-le s'il n'existe pas). - 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).
- Ouvre le niveau à convertir, puis menu Outils → PhysiCore → Exporter vers PhysiCore…
- 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 Unreal | Dans 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ériaux | Ré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és | Le LOD le plus détaillé sous la limite de triangles (le mesh de secours pour Nanite) |
PlayerStart | Points d'apparition (un à l'origine s'il n'y en a pas) |
| Point Light, Spot Light, Rect Light | Lumières et spots (couleur, intensité, portée, angle ; ombres seulement s'il y a 32 lumières ou moins, 80 m d'affichage) |
| Directional Light | Soleil 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églage | Effet |
|---|---|
| Dossier de sortie, nom du dossier de l'addon, titre | L'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és | Exporte la sélection du niveau au lieu de tout le niveau |
| Lumières | Décoché : pas de lumières (le soleil est toujours repris) |
| Triangles max par mesh | 60 000 par défaut |
| Taille max des textures | 2048 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 :
export_asset_pack.py, lancé parUnrealEditor-Cmd.exe Projet.uproject -run=pythonscript -script=…avec-nullrhi: variablesPC_PACK(dossier, ex./Game/ModernCityEnvironment01),PC_OUT(dossier de l'addon),PC_STAGE(dossier de travail) etPC_KIND(StaticMesh, puisSkeletalMesh). 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 ;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 écritprops.jsond'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.
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.
- Copie le dossier
PhysiCoreExporterdansAssets/du projet Unity, ou installe-le avec Package Manager → + → Install package from disk… (fichierpackage.json). - Ouvre la scène, puis menu Tools → PhysiCore → Exporter la scène…
- 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 Unity | Dans 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 / PlayerStart | Points d'apparition (un à l'origine s'il n'y en a pas) |
| Point Light, Spot Light | Lumières et spots (couleur, intensité, portée, angle ; ombres seulement s'il y a 32 lumières ou moins) |
| Directional Light | Soleil 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.
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
- Prends le toolgun (2) et choisis l'outil Duplicateur dans le menu de spawn.
- Clic gauche sur les props à inclure (ils s'éclairent en cyan), puis clic droit pour sauvegarder en lui donnant un nom.
- 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}"
}
]
}
| Champ | Description |
|---|---|
props[].id | Identifiant du prop ou du gadget |
props[].pos / rot | Position (m) et rotation (quaternion x, y, z, w), relatives à l'origine |
props[].frozen, color | Figé ou non ; teinte en hexadécimal RRGGBBAA |
props[].data | Réglages du prop : gadgets (force, touches du pavé numérique, rayon…), matériau, masse |
constraints[].type | weld, nocollide, rope, elastic, axis, ballsocket, winch, slider, keepupright |
constraints[].a / b | Index des props dans la liste props (b = -1 : attaché au monde) |
la / lb | Points d'attache locaux sur a et b (pour le monde : position relative à l'origine) |
axis, params | Axe local (axes, glissières) ; paramètres (longueur de corde, raideur, moteur…) |
Les dupes de la version 1 (sans data ni constraints) restent lisibles.
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
| Limite | Valeur |
|---|---|
| Props par joueur | 200 |
| Distance maximale pour faire apparaître un prop ou une dupe | 60 m autour du joueur |
| Props par dupe | 150 |
| Contraintes par dupe | 300 |
Les props d'une dupe dont l'addon manque sont ignorés ; le joueur est prévenu du nombre de props non créés.