Skip to content

Commit 6125ff0

Browse files
authored
Allow AI to change layers/effects/scene and some game properties (#7799)
1 parent a5428a8 commit 6125ff0

26 files changed

+819
-13
lines changed

Core/GDCore/Extensions/Metadata/MetadataProvider.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,10 @@ class GD_CORE_API MetadataProvider {
277277
return &metadata == &badObjectInfo;
278278
}
279279

280+
static bool IsBadEffectMetadata(const gd::EffectMetadata& metadata) {
281+
return &metadata == &badEffectMetadata;
282+
}
283+
280284
virtual ~MetadataProvider();
281285

282286
private:

Extensions/3D/JsExtension.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1908,7 +1908,9 @@ module.exports = {
19081908
.addEffect('AmbientLight')
19091909
.setFullName(_('Ambient light'))
19101910
.setDescription(
1911-
_('A light that illuminates all objects from every direction.')
1911+
_(
1912+
'A light that illuminates all objects from every direction. Often used along with a Directional light (though a Hemisphere light can be used instead of an Ambient light).'
1913+
)
19121914
)
19131915
.markAsNotWorkingForObjects()
19141916
.markAsOnlyWorkingFor3D()
@@ -1929,7 +1931,11 @@ module.exports = {
19291931
const effect = extension
19301932
.addEffect('DirectionalLight')
19311933
.setFullName(_('Directional light'))
1932-
.setDescription(_('A very far light source like the sun.'))
1934+
.setDescription(
1935+
_(
1936+
"A very far light source like the sun. This is the light to use for casting shadows for 3D objects (other lights won't emit shadows). Often used along with a Hemisphere light."
1937+
)
1938+
)
19331939
.markAsNotWorkingForObjects()
19341940
.markAsOnlyWorkingFor3D()
19351941
.addIncludeFile('Extensions/3D/DirectionalLight.js');
@@ -2013,7 +2019,7 @@ module.exports = {
20132019
.setFullName(_('Hemisphere light'))
20142020
.setDescription(
20152021
_(
2016-
'A light that illuminates objects from every direction with a gradient.'
2022+
'A light that illuminates objects from every direction with a gradient. Often used along with a Directional light.'
20172023
)
20182024
)
20192025
.markAsNotWorkingForObjects()

GDevelop.js/Bindings/Bindings.idl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,6 +1143,7 @@ interface LayersContainer {
11431143
boolean HasLayerNamed([Const] DOMString name);
11441144
void RemoveLayer([Const] DOMString name);
11451145
unsigned long GetLayersCount();
1146+
unsigned long GetLayerPosition([Const] DOMString name);
11461147
void SwapLayers(unsigned long firstLayerIndex, unsigned long secondLayerIndex);
11471148
void MoveLayer(unsigned long oldIndex, unsigned long newIndex);
11481149
void SerializeLayersTo([Ref] SerializerElement element);
@@ -2932,6 +2933,7 @@ interface MetadataProvider {
29322933
boolean STATIC_IsBadInstructionMetadata([Const, Ref] InstructionMetadata metadata);
29332934
boolean STATIC_IsBadBehaviorMetadata([Const, Ref] BehaviorMetadata metadata);
29342935
boolean STATIC_IsBadObjectMetadata([Const, Ref] ObjectMetadata metadata);
2936+
boolean STATIC_IsBadEffectMetadata([Const, Ref] EffectMetadata metadata);
29352937
};
29362938

29372939
enum ProjectDiagnostic_ErrorType {

GDevelop.js/Bindings/Wrapper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,7 @@ typedef std::vector<gd::PropertyDescriptorChoice> VectorPropertyDescriptorChoice
606606
#define STATIC_IsBadInstructionMetadata IsBadInstructionMetadata
607607
#define STATIC_IsBadBehaviorMetadata IsBadBehaviorMetadata
608608
#define STATIC_IsBadObjectMetadata IsBadObjectMetadata
609+
#define STATIC_IsBadEffectMetadata IsBadEffectMetadata
609610

610611
#define STATIC_RenameObjectInEvents RenameObjectInEvents
611612
#define STATIC_RemoveObjectInEvents RemoveObjectInEvents

GDevelop.js/types.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,7 @@ export class LayersContainer extends EmscriptenObject {
941941
hasLayerNamed(name: string): boolean;
942942
removeLayer(name: string): void;
943943
getLayersCount(): number;
944+
getLayerPosition(name: string): number;
944945
swapLayers(firstLayerIndex: number, secondLayerIndex: number): void;
945946
moveLayer(oldIndex: number, newIndex: number): void;
946947
serializeLayersTo(element: SerializerElement): void;
@@ -2109,6 +2110,7 @@ export class MetadataProvider extends EmscriptenObject {
21092110
static isBadInstructionMetadata(metadata: InstructionMetadata): boolean;
21102111
static isBadBehaviorMetadata(metadata: BehaviorMetadata): boolean;
21112112
static isBadObjectMetadata(metadata: ObjectMetadata): boolean;
2113+
static isBadEffectMetadata(metadata: EffectMetadata): boolean;
21122114
}
21132115

21142116
export class ProjectDiagnostic extends EmscriptenObject {

GDevelop.js/types/gdlayerscontainer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ declare class gdLayersContainer {
77
hasLayerNamed(name: string): boolean;
88
removeLayer(name: string): void;
99
getLayersCount(): number;
10+
getLayerPosition(name: string): number;
1011
swapLayers(firstLayerIndex: number, secondLayerIndex: number): void;
1112
moveLayer(oldIndex: number, newIndex: number): void;
1213
serializeLayersTo(element: gdSerializerElement): void;

GDevelop.js/types/gdmetadataprovider.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ declare class gdMetadataProvider {
2626
static isBadInstructionMetadata(metadata: gdInstructionMetadata): boolean;
2727
static isBadBehaviorMetadata(metadata: gdBehaviorMetadata): boolean;
2828
static isBadObjectMetadata(metadata: gdObjectMetadata): boolean;
29+
static isBadEffectMetadata(metadata: gdEffectMetadata): boolean;
2930
delete(): void;
3031
ptr: number;
3132
};

newIDE/app/src/AiGeneration/AskAiEditorContainer.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { I18n } from '@lingui/react';
55
import {
66
type RenderEditorContainerPropsWithRef,
77
type SceneEventsOutsideEditorChanges,
8+
type InstancesOutsideEditorChanges,
89
} from '../MainFrame/EditorContainers/BaseEditor';
910
import { type ObjectWithContext } from '../ObjectsList/EnumerateObjects';
1011
import Paper from '../UI/Paper';
@@ -67,6 +68,7 @@ const useProcessFunctionCalls = ({
6768
getEditorFunctionCallResults,
6869
addEditorFunctionCallResults,
6970
onSceneEventsModifiedOutsideEditor,
71+
onInstancesModifiedOutsideEditor,
7072
onExtensionInstalled,
7173
}: {|
7274
i18n: I18nType,
@@ -85,6 +87,9 @@ const useProcessFunctionCalls = ({
8587
onSceneEventsModifiedOutsideEditor: (
8688
changes: SceneEventsOutsideEditorChanges
8789
) => void,
90+
onInstancesModifiedOutsideEditor: (
91+
changes: InstancesOutsideEditorChanges
92+
) => void,
8893
onExtensionInstalled: (extensionNames: Array<string>) => void,
8994
|}) => {
9095
const { ensureExtensionInstalled } = useEnsureExtensionInstalled({
@@ -159,6 +164,7 @@ const useProcessFunctionCalls = ({
159164
});
160165
},
161166
onSceneEventsModifiedOutsideEditor,
167+
onInstancesModifiedOutsideEditor,
162168
ensureExtensionInstalled,
163169
searchAndInstallAsset,
164170
});
@@ -179,6 +185,7 @@ const useProcessFunctionCalls = ({
179185
searchAndInstallAsset,
180186
generateEvents,
181187
onSceneEventsModifiedOutsideEditor,
188+
onInstancesModifiedOutsideEditor,
182189
triggerSendEditorFunctionCallResults,
183190
editorCallbacks,
184191
]
@@ -349,6 +356,9 @@ type Props = {|
349356
onSceneEventsModifiedOutsideEditor: (
350357
changes: SceneEventsOutsideEditorChanges
351358
) => void,
359+
onInstancesModifiedOutsideEditor: (
360+
changes: InstancesOutsideEditorChanges
361+
) => void,
352362
onExtensionInstalled: (extensionNames: Array<string>) => void,
353363
initialMode: 'chat' | 'agent' | null,
354364
initialAiRequestId: string | null,
@@ -372,6 +382,9 @@ export type AskAiEditorInterface = {|
372382
onSceneEventsModifiedOutsideEditor: (
373383
changes: SceneEventsOutsideEditorChanges
374384
) => void,
385+
onInstancesModifiedOutsideEditor: (
386+
changes: InstancesOutsideEditorChanges
387+
) => void,
375388
startOrOpenChat: ({|
376389
mode: 'chat' | 'agent',
377390
aiRequestId: string | null,
@@ -401,6 +414,7 @@ export const AskAiEditor = React.memo<Props>(
401414
onCreateProjectFromExample,
402415
onOpenLayout,
403416
onSceneEventsModifiedOutsideEditor,
417+
onInstancesModifiedOutsideEditor,
404418
onExtensionInstalled,
405419
initialMode,
406420
initialAiRequestId,
@@ -518,6 +532,7 @@ export const AskAiEditor = React.memo<Props>(
518532
onSceneObjectEdited: noop,
519533
onSceneObjectsDeleted: noop,
520534
onSceneEventsModifiedOutsideEditor: noop,
535+
onInstancesModifiedOutsideEditor: noop,
521536
startOrOpenChat: onStartOrOpenChat,
522537
}));
523538

@@ -655,6 +670,7 @@ export const AskAiEditor = React.memo<Props>(
655670
fileMetadata,
656671
storageProviderName,
657672
mode,
673+
toolsVersion: 'v2',
658674
aiConfiguration: {
659675
presetId: aiConfigurationPresetId,
660676
},
@@ -944,6 +960,7 @@ export const AskAiEditor = React.memo<Props>(
944960
getEditorFunctionCallResults,
945961
addEditorFunctionCallResults,
946962
onSceneEventsModifiedOutsideEditor,
963+
onInstancesModifiedOutsideEditor,
947964
i18n,
948965
onExtensionInstalled,
949966
});
@@ -1044,6 +1061,9 @@ export const renderAskAiEditorContainer = (
10441061
onSceneEventsModifiedOutsideEditor={
10451062
props.onSceneEventsModifiedOutsideEditor
10461063
}
1064+
onInstancesModifiedOutsideEditor={
1065+
props.onInstancesModifiedOutsideEditor
1066+
}
10471067
onExtensionInstalled={props.onExtensionInstalled}
10481068
initialMode={
10491069
(props.extraEditorProps && props.extraEditorProps.mode) || null

newIDE/app/src/EditorFunctions/EditorFunctionCallRunner.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
type AssetSearchAndInstallOptions,
1111
type AssetSearchAndInstallResult,
1212
type SceneEventsOutsideEditorChanges,
13+
type InstancesOutsideEditorChanges,
1314
} from '.';
1415

1516
export type EditorFunctionCallResult =
@@ -39,6 +40,9 @@ export type ProcessEditorFunctionCallsOptions = {|
3940
onSceneEventsModifiedOutsideEditor: (
4041
changes: SceneEventsOutsideEditorChanges
4142
) => void,
43+
onInstancesModifiedOutsideEditor: (
44+
changes: InstancesOutsideEditorChanges
45+
) => void,
4246
ensureExtensionInstalled: (options: {|
4347
extensionName: string,
4448
|}) => Promise<void>,
@@ -53,6 +57,7 @@ export const processEditorFunctionCalls = async ({
5357
editorCallbacks,
5458
generateEvents,
5559
onSceneEventsModifiedOutsideEditor,
60+
onInstancesModifiedOutsideEditor,
5661
ignore,
5762
ensureExtensionInstalled,
5863
searchAndInstallAsset,
@@ -136,6 +141,7 @@ export const processEditorFunctionCalls = async ({
136141
args,
137142
generateEvents,
138143
onSceneEventsModifiedOutsideEditor,
144+
onInstancesModifiedOutsideEditor,
139145
ensureExtensionInstalled,
140146
searchAndInstallAsset,
141147
}

newIDE/app/src/EditorFunctions/SimplifiedProject/ExtensionSummary.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ export type ExpressionSummary = {|
3232
relevantForSceneEvents?: boolean,
3333
|};
3434

35+
export type PropertySummary = {|
36+
name: string,
37+
description: string,
38+
type: string,
39+
|};
40+
3541
export type ObjectSummary = {|
3642
name: string,
3743
fullName: string,
@@ -51,6 +57,17 @@ export type BehaviorSummary = {|
5157
expressions: Array<ExpressionSummary>,
5258
|};
5359

60+
export type EffectSummary = {|
61+
name: string,
62+
fullName: string,
63+
description: string,
64+
notWorkingForObjects: boolean,
65+
onlyWorkingFor2D: boolean,
66+
onlyWorkingFor3D: boolean,
67+
unique: boolean,
68+
properties: Array<PropertySummary>,
69+
|};
70+
5471
export type ExtensionSummary = {|
5572
extensionName: string,
5673
extensionFullName: string,
@@ -60,6 +77,7 @@ export type ExtensionSummary = {|
6077
freeExpressions: Array<ExpressionSummary>,
6178
objects: { [string]: ObjectSummary },
6279
behaviors: { [string]: BehaviorSummary },
80+
effects: { [string]: EffectSummary },
6381
|};
6482

6583
const normalizeType = (parameterType: string) => {
@@ -102,6 +120,29 @@ const getParameterSummary = (
102120
return parameterSummary;
103121
};
104122

123+
const getPropertySummary = (
124+
propertyName: string,
125+
property: gdPropertyDescriptor
126+
) => {
127+
return {
128+
name: propertyName,
129+
description: property.getDescription(),
130+
type: property.getType(),
131+
};
132+
};
133+
134+
const getPropertiesSummary = (
135+
propertiesMetadata: gdMapStringPropertyDescriptor
136+
) => {
137+
return propertiesMetadata
138+
.keys()
139+
.toJSArray()
140+
.map(propertyName => {
141+
const property = propertiesMetadata.get(propertyName);
142+
return getPropertySummary(propertyName, property);
143+
});
144+
};
145+
105146
export const buildExtensionSummary = ({
106147
gd,
107148
extension,
@@ -111,6 +152,7 @@ export const buildExtensionSummary = ({
111152
}): ExtensionSummary => {
112153
const objects: { [string]: ObjectSummary } = {};
113154
const behaviors: { [string]: BehaviorSummary } = {};
155+
const effects: { [string]: EffectSummary } = {};
114156

115157
const generateInstructionsSummaries = ({
116158
instructionsMetadata,
@@ -254,6 +296,27 @@ export const buildExtensionSummary = ({
254296

255297
behaviors[behaviorType] = behaviorSummary;
256298
});
299+
extension
300+
.getExtensionEffectTypes()
301+
.toJSArray()
302+
.forEach(effectType => {
303+
const effectMetadata = extension.getEffectMetadata(effectType);
304+
if (gd.MetadataProvider.isBadEffectMetadata(effectMetadata)) {
305+
return;
306+
}
307+
const effectSummary: EffectSummary = {
308+
name: effectMetadata.getType(),
309+
fullName: effectMetadata.getFullName(),
310+
description: effectMetadata.getDescription(),
311+
notWorkingForObjects: effectMetadata.isMarkedAsNotWorkingForObjects(),
312+
onlyWorkingFor2D: effectMetadata.isMarkedAsOnlyWorkingFor2D(),
313+
onlyWorkingFor3D: effectMetadata.isMarkedAsOnlyWorkingFor3D(),
314+
unique: effectMetadata.isMarkedAsUnique(),
315+
properties: getPropertiesSummary(effectMetadata.getProperties()),
316+
};
317+
318+
effects[effectType] = effectSummary;
319+
});
257320

258321
return {
259322
extensionName: extension.getName(),
@@ -275,5 +338,6 @@ export const buildExtensionSummary = ({
275338
],
276339
objects,
277340
behaviors,
341+
effects,
278342
};
279343
};

0 commit comments

Comments
 (0)