Skip to content

Commit 08958dd

Browse files
committed
Restore Colors toolbox entry and implement palette generator controls - PR_26159_024-colors-toolbox-admin-visibility
1 parent cee4b35 commit 08958dd

13 files changed

Lines changed: 1236 additions & 70 deletions

assets/theme-v2/css/forms.css

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,57 @@ input[type="color"][data-palette-swatch-size="large"] {
213213
pointer-events: none
214214
}
215215

216+
.palette-generator-preview {
217+
display: flex;
218+
flex-direction: column;
219+
gap: var(--space-3);
220+
width: 100%;
221+
min-height: calc(var(--space-78) * 4)
222+
}
223+
224+
.palette-generator-preview-row {
225+
display: flex;
226+
flex: 1 1 0;
227+
gap: var(--space-3);
228+
min-height: var(--space-0);
229+
width: 100%
230+
}
231+
232+
.palette-generator-preview-swatch {
233+
display: flex;
234+
flex: 1 1 0;
235+
min-width: var(--space-0);
236+
min-height: var(--space-0)
237+
}
238+
239+
.palette-generator-preview-swatch input[type="color"] {
240+
box-sizing: border-box;
241+
width: 100%;
242+
min-width: var(--space-0);
243+
height: 100%;
244+
min-height: var(--space-0);
245+
padding: var(--space-0);
246+
border: var(--border-width-sm) solid var(--line);
247+
border-radius: var(--radius-xs);
248+
background: var(--transparent);
249+
overflow: hidden;
250+
pointer-events: none
251+
}
252+
253+
.palette-generator-preview-swatch input[type="color"]::-webkit-color-swatch-wrapper {
254+
padding: var(--space-0)
255+
}
256+
257+
.palette-generator-preview-swatch input[type="color"]::-webkit-color-swatch {
258+
border: var(--border-width-sm) solid var(--line);
259+
border-radius: var(--radius-xs)
260+
}
261+
262+
.palette-generator-preview-swatch input[type="color"]::-moz-color-swatch {
263+
border: var(--border-width-sm) solid var(--line);
264+
border-radius: var(--radius-xs)
265+
}
266+
216267
.palette-swatch-tile:hover,
217268
.palette-swatch-tile:focus-visible {
218269
box-shadow: 0 0 0 var(--space-3) var(--gold-soft), 0 0 var(--space-18) var(--orange-shadow-color);
Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
https://chatgpt.com/g/g-p-69dd3dc714488191ade02daaad81267f/c/6a1b45ea-b810-83ea-bf20-0d8695de18a7
2+
3+
4+
My recommendation:
5+
6+
Database = source of truth
7+
Tools = edit specific records
8+
Game manifest = playable/publishable game contract
9+
10+
Workspace should become more like a working session/project container, not the thing that permanently ties everything together.
11+
12+
Better model
13+
1. Tool data stored separately
14+
15+
Each tool owns structured data:
16+
17+
palettes
18+
sprites/vector assets
19+
tilemaps/worlds
20+
objects/entities
21+
input mappings
22+
audio/music
23+
collision profiles
24+
UI layouts
25+
behaviors/rules
26+
GDD
27+
validation results
28+
29+
These live as database records with IDs, versions, owner, project/game ID, timestamps, etc.
30+
31+
2. Game manifest references approved data
32+
33+
game.manifest.json should not become a giant dump of every editor’s internal state.
34+
35+
It should contain the runtime-ready game definition:
36+
37+
game title/details
38+
scenes
39+
assets used by runtime
40+
entity definitions
41+
rules/components
42+
input map references
43+
world/map references
44+
audio references
45+
publish settings
46+
version
47+
48+
So the manifest becomes:
49+
“Here is what the engine needs to run this game.”
50+
51+
Not:
52+
“Here is every tool’s editable workspace state.”
53+
54+
3. Workspace becomes optional/editing context
55+
56+
Workspace can still exist, but as:
57+
58+
current open project
59+
selected tool state
60+
draft edits
61+
layout/panel preferences
62+
unsaved working data
63+
user-specific UI state
64+
65+
It should not be required for the game to run.
66+
67+
The big rule
68+
69+
Tool data is authoring data.
70+
Manifest data is runtime data.
71+
Workspace data is session/UI data.
72+
73+
That separation is very powerful.
74+
75+
Example
76+
77+
Instead of this:
78+
79+
workspace
80+
├─ palette data
81+
├─ sprite data
82+
├─ map data
83+
├─ input data
84+
└─ game manifest
85+
86+
Do this:
87+
88+
database
89+
├─ projects
90+
├─ games
91+
├─ gdds
92+
├─ assets
93+
├─ palettes
94+
├─ maps
95+
├─ objects
96+
├─ input_mappings
97+
├─ music
98+
├─ validation_results
99+
└─ manifests
100+
101+
Then:
102+
103+
game.manifest.json
104+
├─ game details
105+
├─ runtime assets
106+
├─ runtime scenes
107+
├─ runtime objects
108+
├─ runtime rules
109+
└─ references/version IDs
110+
Bottom line
111+
112+
Yes, I would move away from tightly linked Workspace.
113+
114+
I would make:
115+
116+
GDD → validates → generates/updates tool records → builds game.manifest.json → engine runs manifest
117+
118+
That gets you closer to a real platform:
119+
120+
easier database storage
121+
easier versioning
122+
easier AI assistance
123+
easier publishing
124+
easier collaboration
125+
easier rollback
126+
less fragile JSON
127+
no giant “workspace blob” problem
128+
129+
Workspace should be a convenience layer, not the backbone.
130+
131+
How do be build the rules part, is it at the object level, Hero, Enimy, etc?
132+
133+
Yes — mostly object type level, with overrides per object instance.
134+
135+
Best structure:
136+
137+
Object Type
138+
Hero
139+
rules
140+
components
141+
inputs
142+
physics
143+
collisions
144+
health
145+
animations
146+
147+
Object Instance
148+
hero_001
149+
type: Hero
150+
position
151+
overrides
152+
153+
So you define reusable types:
154+
155+
Hero
156+
Enemy
157+
Projectile
158+
Wall
159+
Pickup
160+
Hazard
161+
Platform
162+
Goal
163+
164+
Each type has rules like:
165+
166+
{
167+
"type": "Hero",
168+
"components": ["moveable", "health", "playerInput", "worldBoundsBounce"],
169+
"rules": {
170+
"onCollision": {
171+
"Enemy": ["takeDamage", "knockback"],
172+
"Pickup": ["collect"],
173+
"Wall": ["bounce"]
174+
},
175+
"onFall": ["takeDamage"],
176+
"onHealthZero": ["playDeathAnimation", "respawn"]
177+
}
178+
}
179+
180+
Then each placed object can override small things:
181+
182+
{
183+
"id": "hero_001",
184+
"type": "Hero",
185+
"x": 100,
186+
"y": 200,
187+
"overrides": {
188+
"health.max": 150,
189+
"movement.speed": 4
190+
}
191+
}
192+
193+
The key idea:
194+
195+
Object Type = what it is and how it behaves
196+
Object Instance = where it is and what is different this time
197+
198+
For your engine, I’d use:
199+
200+
1. Object type rules
201+
2. Scene rules
202+
3. Global game rules
203+
4. Instance overrides
204+
205+
Example:
206+
207+
Global rule:
208+
- water damages anything with health
209+
210+
Scene rule:
211+
- this level has low gravity
212+
213+
Object type rule:
214+
- Hero can jump and take damage
215+
216+
Instance override:
217+
- this enemy has 2x health
218+
219+
This is exactly how you avoid user-written code while still getting powerful behavior.
220+
221+
The user configures:
222+
223+
Hero collides with Enemy → take damage + bounce
224+
Enemy collides with Hero → deal damage
225+
Projectile collides with Enemy → reduce health + destroy projectile
226+
Pickup collides with Hero → add score + remove pickup
227+
228+
So yes: Hero, Enemy, Projectile, Pickup, Wall, Platform, Hazard should all become configurable object types with rules attached.
229+
230+
Should we create objects based on Static, movable, killable, etc, that would be where rules live?
231+
232+
Yes — but name them as capabilities, not inheritance classes.
233+
234+
Use:
235+
236+
Object Type: Hero
237+
Capabilities:
238+
- renderable
239+
- movable
240+
- collidable
241+
- killable
242+
- playerControlled
243+
- damageDealer
244+
245+
Not:
246+
247+
Hero extends ObjectKillable extends ObjectDynamic
248+
249+
Rules should live on the object type, using those capabilities.
250+
251+
Example:
252+
253+
{
254+
"type": "Hero",
255+
"base": "movableKillable",
256+
"capabilities": {
257+
"movement": true,
258+
"health": true,
259+
"collision": true,
260+
"input": true
261+
},
262+
"rules": {
263+
"onCollision": {
264+
"Enemy": ["takeDamage", "knockback"],
265+
"Pickup": ["collect"]
266+
},
267+
"onHealthZero": ["startDeathAnimation", "respawn"]
268+
}
269+
}
270+
271+
Better pattern:
272+
273+
Base archetype:
274+
- static
275+
- movable
276+
- killable
277+
- movableKillable
278+
- projectile
279+
- pickup
280+
- hazard
281+
- platform
282+
283+
Game object type:
284+
- Hero
285+
- Enemy
286+
- Bullet
287+
- Ice Block
288+
- Coin
289+
- Wall
290+
291+
So:
292+
293+
Wall = static + collidable
294+
Hero = movable + killable + input
295+
Enemy = movable + killable + AI
296+
Bullet = movable + damageDealer + expires
297+
Pickup = static + collectible
298+
Ice Cube = movable + collidable + damageDealer
299+
300+
The important split:
301+
302+
Capabilities say what systems apply.
303+
Rules say what happens.
304+
305+
Example:
306+
307+
capability: killable
308+
rules:
309+
- has health
310+
- can take damage
311+
- can die
312+
- can play death animation
313+
314+
capability: movable
315+
rules:
316+
- has velocity
317+
- affected by gravity
318+
- can bounce
319+
- can be knocked back
320+
321+
So yes: build object types from static, movable, killable, etc. But do not lock yourself into a rigid class tree. Use composable capabilities/components so one object can be:
322+
323+
movable + killable + collectible
324+
325+
or
326+
327+
static + damageDealer + destructible
328+
329+
That will be much more powerful for Game Foundry Studio.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[ ] We need to use the add button to add a row to a table.
2+
[ ] more like a table that is an in place editor

0 commit comments

Comments
 (0)