#Version 12 Deep Dive - Primary Canvas Objects V2
1 messages · Page 1 of 1 (latest)
Version 12 Deep Dive - Primary Canvas
Version 12 Deep Dive - Primary Canvas Objects V2
On https://github.com/foundryvtt/foundryvtt/issues/6751, does that mean elevation rather than stacking order? How does that jive with the new [/] keybinds?
just for sanity: this is an overhaul of existing canvas objects/placables, like lights, sounds and tiles, correct?
yah
though "primary canvas object" might come with creeping away from inherent ties to documents
that would be my next question, if anything here would help define new placables + hud (like cards)
I highly suspect the answer is no, but it doesn't hurt to ask 😄
Some terminology to be aware of. Certain types of Document are CanvasDocument, i.e. ones that are embedded in a Scene and placed onto the canvas.
Each CanvasDocument is associated with a PlaceableObject (1:1) where the CanvasDocument is the data structure and the PlaceableObject is an intermediary layer that translates that data structure into how the thing should be rendered on the canvas, and also provides interactivity UI/UX for modifying the document.
The actual rendering of each object is handled by the PrimaryCanvasObject, usually a PrimarySpriteMesh. So the PlaceableObject manages a PrimarySpriteMesh which is responsible for rendering.
It's a bit complicated, but it is necessarily complicated in order to have separation of concerns between:
- Data Model (the
Document) - Interactivity (the
PlaceableObject) - Rendering (the
PrimaryCanvasObject)
One very important feature of this V12 overhaul is that you can now create PrimaryCanvasObjects directly in order to render... anything you want... to the canvas
So if you have a use case for doing something visual, you can do it by bypassing the whole Document -> PlaceableObject -> PrimaryCanvasObject pipeline and instead just rendering a PrimaryCanvasObject directly.
It puts more control in the hands of developers to do whatever they want to do in more possible ways without needing to fight the system of "is this a Document"
I was just getting to typing PrimaryCanvasObjects in v11. From a high level view, are these "we've thrown everything out" like you did with lighting, or is this more enhancements to the existing API?
This same philosophy is inherent in our V12 audio work (#1166858723092865044) which makes it easier to create a low-level Sound directly without needing a Playlist, PlaylistSound, or AmbientSound document.
The changes are extensive. I would recommend that you invest time into the v11 types only if you feel that is extremely valuable to have for the next 3-4 months.
It's work you will pretty much have to re-do in V12.
my understanding was that's already possible, by adding a layer and defining the objects (as sprites IIRC) and then drawing the layer. How is this new implementation different from the current approach?
Just for my own reference, this is a total redo of the classes in client/pixi/placeables?
Just more powerful and feature-complete. There were some behaviors that were inherently linked to PlaceableObjects in order to function properly (like overhead occlusion).
I see thanks
We have worked hard to ensure that anything that is a rendering behavior is fully de-coupled from Document / PlaceableObject
fingers crossed this will make placeable cards easier to implement 😄
but I am excited either way
You wouldn't need a layer though. Objects in the PrimaryCanvasGroup are all siblings which are sorted according to their elevation and sort properties.
A separate canvas layer would be useful for things like HUD/UI/interactivity controls.
Sounds like we're gonna remove that ticket from the current milestone 😂 I'll get Headquarters done and then that's basically the 3.3 milestone
makes sense to me lol
This is a really great update, thanks Foundry team
FWIW we expect Prototype 1 to drop later today, so you'll be able to look at the code for the new PCO stuff imminently.
So if I understand this correctly,. the tokens on a scene as placeableobjects aren't directly changed by this, just their rendered form as a PrimaryCanvasObject? (I'm trying to work out if the noted changes will eventually mean token.data is going away but I don't think it is?)
umm... well... Token#data was deprecated in v10 and is removed in V12 so... yes, that is (and was since v10) going away
but that is unrelated to PCO changes
@halcyon sail https://github.com/foundryvtt/foundryvtt/issues/10164
Sorry, silly me, I get everything from token.actor I think.
Is there a plan as part of v12 to enable setting a default elevation for primaryCanvasObjects of particular types? Like setting all drawings to a higher elevation so they are on top by default? Edit: I bet you'll tell me we can set this in our own systems by having a system setting and then overriding the elevation in the precreate method or something like that. 🙂
Yeah, that sounds like a preCreate hook to me
I'm hoping the work on scene zones may allow me to leverage that for some metadata/annotations that I currently have to use the drawing layer for.
Can somebody provide an example of a common piece of code that some systems/modules/macros probably use and that would break in V12 (unless a new API is added)?
Do you mean stuff other than things already throwing deprecation warnings about how they'll break in V12?
yes, something new (perhaps something that uses TokenMesh directly?)
I mean, a lot of modules just don't touch Canvas
(Thankfully v12 doesn't look to be trying to break the core Document API again)
From what I'm seeing, I doubt any of the breaking changes listed touch things that I would call "common usage" in any systems/modules/macros. I'm sure there are some things that will be hit by them, but not common stuff
Realistically, anything that is commonly used is gonna be stuff staff know about and will have a deprecation path for
The thing to look out for most devs is not this prototype but the next, when they rollout app v2
we have the second most popular system, so what we do is common 🙂
Commonly run code != commonly written code
I guess!
Some quick rules of thumb might be:
- If your code does not contain
new TokenMesh(ornew TileMesh(you are probably unaffected by the PCO changes. - If your code does not contain
new Sound(you are probably unaffected by the Audio API changes.
I would enhance the quick rules of thumb by noting that if you are utilizing the v11 PrimaryCanvasObject#initialize method in your module or system, you will be impacted by the v12 changes.
Hello, me again, are there any changes in v12 as far as tinkering with the token HUD with stuff like:
Hooks.on('renderTokenHUD', function (hudButtons, html, data) {
var users = game.users.contents;
var user = users.find(user => user?.character?.id === data.actorId)
if (user) {
let button = $(`<div class="control-icon whisperBox"><i class="fa fa-user-secret"></i></div>`);
let col = html.find('.col.left');
col.append(button);
button.find('i').click(async (ev) => {
let name = user.name;
if(game.settings.get('WhisperBox', 'showCharacterName')){
name = user?.character?.name ?? name;
}
let whisperBoxData = {
name: name,
targetUser: user.id
}
WhisperBox.createWhisperBox(whisperBoxData);
});
}
});```
Are you asking because you are noticing a problem? There were some new buttons added to the token hud in v12 for token stacking
No, it's working fine in Whisperbox, but I'm not sure if there's new tricks or anything. I want to implement a new feature that uses the token HUD. I think I also need to add a pop-out interface to it and am wondering about the best way to do it.
AFAIK, TokenHUD is an Application, not a Pixi canvas object at all
I think you're right, yes.
Is there a simple way to trigger a fade or transform effect on the token mesh when updating the token artwork in v12?
its possible but hard now. There may be an easier way after Prototype 2 is released. We have some plans
I can wait, no worries. 🙂
Looks like the V12 canvas breaks how I was offering players a "reveal map" feature. I was using a code snippet I found in the macro channel
it creates an ambient light the size of the scene. With vision and no walls. Then quickly deletes it
const dimensions = canvas.scene.dimensions
let [created_light] = await canvas.scene.createEmbeddedDocuments('AmbientLight', [{dim: dimensions.maxR, vision: true, walls: false, x: dimensions.width/2, y: dimensions.height/2}])
await new Promise(r => setTimeout(r, 100))
await created_light.update({hidden: true})
await created_light.delete()
I spend a day looking at how Foundry does its fog exploration a few months ago and tried to write my own which creates a full red (explored) base64Image and trying different calls to the fog explorer class. But wasn't ever able to get something as nice as the above code (or that didn't break the players vision in some way, requiring reload).
I looked at how other modules like simplefog and world-explorer revealed fog of war. But was disappointed to find they create a layer above and just interact with that.
Is there any kind of "recommended" (putting recommended in quotes because I'm aware this is on the lower end of APIs) route for developing a module exploration feature in V12. I would be very happy to learn more about any one of the following functionalities:
- give all connected players full exploration on current scene (I would think this is easiest to implement)
- give a single player full exploration
- same as 1 or 2 but for partial exploration (a box or circle portion of the scene around a specified coordinate)
Will primary canvas objects make it easier to add a hud to custom objects?
or is that an entirely different issue?
Unrelated. Adding a custom HUD would involve defining your hud as an application subclass and then defining some conditions under which it is rendered
PCO is more low level just about how we render things on the canvas to begin with
gotcha gotcha, thanks anyway!
custom huds for custom canvas objects is something I've been looking into, thus the question
I believe I have a new implementation of a "map reveal" feature I mentioned a few messages up. It uses the fog manager directly and calls the FogExploration class's updateSource method. I use a 92 character base64 webp to write a new exploration image.
But I do get an error of Error: Texture Extractor is not supporting premultiplied textures yet
Which is caused from the base texture it creates having a value of 1 for alphaMode. Not sure how to get rid of the error
Slightly off-topic for this thread, but I think @hushed plover can provide some guidance for how to overcome this alphaMode issue
Hello! The base texture should be loaded as non premultiplied (PIXI.ALPHA_MODES.NO_PREMULTIPLIED_ALPHA).
Question for how the new primary canvas objects work:
If I'm understanding correctly, objects no longer need to be tied to a Document when created on the canvas. So can you create a canvas object (lets say, a light source) and then tie it to another canvas object directly (e.g. a tile).
The reason I ask is because you currently need a module to attach a light to a tile so they move together when dragged. Will this be possible out-of-the-box with v12?
You can create a sprite mesh (the visual part of a tile) without a Tile document. You can create a light source (the visual part of a light) without an Ambient Light document.
Attaching them together so they move in unison is possible but requires code to do it, it doesn’t just happen “out of the box”
You should think of the PCO framework and enhancements as dev-empowering features rather than user-empowering features
Ok. So I could potentially write a macro or module that creates the two meshes and then merges them together, but it’s not going to be a UI feature. Good to know!
Well… sort of. You wouldn’t be merging meshes together but you could implement some code to keep their transforms (position size shape etc) aligned
I believe this is where I post to comment on the canvas/lighting stuff? I'm noticing that you no longer use DetectionMode.BASIC_MODE_ID, and now its hardcoded to basicSight. That doesn't affect us in PF2e land but since BASIC_MODE_ID is no longer referenced by anything I might as well let you all know.
However I'm seeing there's a lightPerception detection mode that is added alongside basicSight. Is there a good summary of what happened there?
Yeah. Sorry for the late answer. Don't hesitate to ping me 🙂
It is Eber's improvements to detection modes:
- Basic Sight is the Darkness detection mode, it allows to see in areas not illuminated in its radius.
- Light Perception is a detection mode able to perceive light sources. The range is illimited by default. It is the "natural" human eye perception.
I'll do so next time then, thanks for the summary.