Introducing Archimedes 3 - A building plugin

I have encountered a small issue with this plugin. I am using the widget mode. Basically, what I did was:

  • Click the arrow next to the Direction Tab
  • Tried to click it again
  • This insane stack trace appeared in the output. Probably the biggest I have ever seen in my entire life

When closing the plugin, opening it again doesn’t work and the plugin remains nonfunctional until you restart studio. Not sure if this is related to the plugin or if this is related to the studio-like roact components you use.

Stack trace in full detail
  cloud_144938633.Archimedes.Modules.Interface.Roact.createSignal:37: Listeners can only be disconnected once.
  Stack Begin
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createSignal', Line 37 - function disconnect
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.RobloxRenderer', Line 100 - function detachAllBindings
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.RobloxRenderer', Line 235 - function unmountHostNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 175 - function unmountVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 370 - function __unmount
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 181 - function unmountVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 370 - function __unmount
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 181 - function unmountVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 370 - function __unmount
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 181 - function unmountVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 370 - function __unmount
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 181 - function unmountVirtualNode
   ▼ Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 188 - function unmountVirtualNode (x2)
     Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 188 - function unmountVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.RobloxRenderer', Line 232 - function unmountHostNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 175 - function unmountVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 370 - function __unmount
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 181 - function unmountVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 370 - function __unmount
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 181 - function unmountVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 257 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 144 - function updateVirtualNodeWithChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 223 - function updateFragmentVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 278 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 144 - function updateVirtualNodeWithChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.RobloxRenderer', Line 271 - function updateHostNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 270 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 149 - function updateVirtualNodeWithRenderResult
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 499 - function __resolveUpdate
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 437 - function __update
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 274 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 149 - function updateVirtualNodeWithRenderResult
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 499 - function __resolveUpdate
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 437 - function __update
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 274 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 149 - function updateVirtualNodeWithRenderResult
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 499 - function __resolveUpdate
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 437 - function __update
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 274 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 149 - function updateVirtualNodeWithRenderResult
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 499 - function __resolveUpdate
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 437 - function __update
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 274 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 149 - function updateVirtualNodeWithRenderResult
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 499 - function __resolveUpdate
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 437 - function __update
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 274 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 149 - function updateVirtualNodeWithRenderResult
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 499 - function __resolveUpdate
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 437 - function __update
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 274 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 149 - function updateVirtualNodeWithRenderResult
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 499 - function __resolveUpdate
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 437 - function __update
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 274 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 144 - function updateVirtualNodeWithChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 223 - function updateFragmentVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 278 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 149 - function updateVirtualNodeWithRenderResult
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 499 - function __resolveUpdate
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 437 - function __update
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 274 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 144 - function updateVirtualNodeWithChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 223 - function updateFragmentVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 278 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 144 - function updateVirtualNodeWithChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.RobloxRenderer', Line 271 - function updateHostNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 270 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 144 - function updateVirtualNodeWithChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.RobloxRenderer', Line 271 - function updateHostNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 270 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 144 - function updateVirtualNodeWithChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.RobloxRenderer', Line 271 - function updateHostNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 270 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 149 - function updateVirtualNodeWithRenderResult
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 499 - function __resolveUpdate
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 437 - function __update
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 274 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 149 - function updateVirtualNodeWithRenderResult
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 499 - function __resolveUpdate
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 437 - function __update
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 274 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 144 - function updateVirtualNodeWithChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.RobloxRenderer', Line 271 - function updateHostNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 270 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 149 - function updateVirtualNodeWithRenderResult
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 499 - function __resolveUpdate
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 437 - function __update
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 274 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 144 - function updateVirtualNodeWithChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 217 - function updatePortalVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 276 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 149 - function updateVirtualNodeWithRenderResult
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 499 - function __resolveUpdate
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 437 - function __update
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 274 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 149 - function updateVirtualNodeWithRenderResult
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 499 - function __resolveUpdate
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 437 - function __update
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 274 - function updateVirtualNode
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 84 - function updateChildren
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.createReconciler', Line 149 - function updateVirtualNodeWithRenderResult
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 499 - function __resolveUpdate
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 437 - function __update
  Script 'cloud_144938633.Archimedes.Modules.Interface.Roact.Component', Line 161 - function setState
  Script 'cloud_144938633.Archimedes.Modules.Interface.PluginComponents.Main', Line 94
  Stack End

I love this plugin…

Thanks for your work, it’s great for us developers, we really appreciate it

  • Suggestion:
    Perhaps it would be a good idea if the “Enabled” button could be toggled with a Shortcut, for example by pressing Tab

The selection part glitch when I open Archimedes 3.

I select a part, but it’s locked.

1 Like

Hello. Why can’t I set both Pitch and Roll angles? I’m trying to make a spiral like this:

Thank you.

Archimedes is trying to automatically apply the absolute best fit for the parts based on the edge that the Alignment mode is set to.

With multiple directions selected, there isn’t really a point like this where that’s possible for a cube, at least not for an absolutely perfect fit as shown here. Which is why plugins that try to solve this problem usually end up filling the space with wedges instead.

It’s possible to change the plugin so that you can select multiple directions at once, but in most cases (not yours, though) it’d result in some very ugly overlapping of the parts, which I felt would just be confusing and make the plugin look bad to beginner users, so I didn’t want to make this the default behavior, especially since in testing I ended up with results like these whenever allowing multiple directions to be toggled:


I have considered adding a separate checkbox in the settings that’s disabled by default but will allow more advanced users to just skip over the forced alignment and do whatever they want. I’ve been getting more and more requests to add this, so I probably will in the next version, which I’ve been busy working on in my free time.


If you’re in widget mode then you may be able to enable the “Auto-Resize” checkbox to kind of automatically correct for the gaps shown in your image, but you’d still have to alternate between directions. I recommend disabling that checkbox as soon as you don’t need it since that feature is still highly unstable and was coded rather poorly at the time.

If Auto-Resize doesn’t work for you in this case then I’m afraid that the moment you’ll just have to manually ResizeAlign to correct those gaps in your image.

Edit: Marked this out since you likely had to do quite a bit of that manually in your image in the first place, given the gaps between some of the parts, so the Auto-Resize suggestion here is pointless.

2 Likes

Oh, I don’t mind if it’s a bit rough in this case. Just need the inside part somewhat aligned. I ended up writing some code to generate it this way: (and chopped off some of the sticking-out bits)

local model = Instance.new("Model")
model.Parent = workspace

local lastpart = workspace["Part"]:Clone()
lastpart.Parent = model

for i=1,36 do
  local part = lastpart:Clone()
  part.CFrame = part.CFrame * CFrame.new(0,0,-2.5) * CFrame.Angles(math.rad(10),0,math.rad(1)) 
  part.Parent = model
  lastpart = part
end
wait(1)
for _,part in next, model:GetChildren() do
	part.CFrame = part.CFrame * CFrame.new(part.Size.X/4,0,0)
	part.Size = part.Size * Vector3.new(.5,1,1)
end

loopgen

I need a more streamlined elegant solution :sob:

By the way, I actually like that generation technique with the cubes. They’re cool road-like obstacles for physics-based games, like mine! I can see that being useful for spiral staircases too, or some chandelier or design

There is actually already a very finicky and inelegant (I know, exactly the opposite of what you asked for, hooray) solution for this in the live version of Archimedes right now that I think is just barely worth mentioning - which is that Archimedes has fields for position and orientation offset vectors. The inelegant part is that there are no ArcHandles or regular movement Handles created for setting these values, so you have to type them in manually. I do plan on adding Handles for this option pretty soon.

If you have the latest version, the fields should be down towards the bottom of the UI in Widget mode.

And, my personal favourite use of this feature, to quickly create a spiral staircase, you can just set the Y offset equal to the height of the part:

2 Likes

Can be solved by disabling collisions on the “ghost” part

Is it alright if i make my own fork of the plugin for public use, mainly just wanting to add a count option
IE: If I have a part called
Part

If i run the plugin it will add a number, the part made will be the first name + number
in order
Part
Part1
Part2
Part3
etc

It’s “open source” (quotes because the plugin isn’t currently on GitHub, you just have to grab the source from your plugin directory) so yes, although I am working on Archimedes 4 currently (see Read Me at the top of this page), which will immediately be on GitHub. All of the code has been or is in the process of being rewritten and it will have the count feature that you are talking about because someone has dm’ed me before asking for the exact same thing. So if you want to make your own forks then I’d highly recommend waiting until then because Archimedes 3 was coded with very beginner knowledge on Roact and was therefore done incorrectly in many places, causing some occasional input delay as well as other problems.

Also, disabling collision on the specific part (in this case, the “ghost” part) does nothing in this case because the studio dragger still allows you to drag objects onto one another even with CanCollide turned off.

Wouldnt disabling the other two collision properties, or just changing the collision group possibly help?

And is there an estimate of 4?

As far as I’m aware, there aren’t two other collision properties, at least not ones related to the conversation. If you’re meaning CanTouch and CanQuery, they have nothing to do with this. The studio dragger also does not care about collision groups. You can easily test your suggestions by applying them to a part in studio and then attempting to drag a part on top of them (only saying this so we don’t end up spamming the thread here going back and forth) - the dragger will detect the other part and cause the actively dragged one to go on top of the other. I know what the problem is - I was just replying to your claim that the issue before could be solved simply by disabling collisions, which isn’t true.

I do not have an estimate and don’t like to give estimates since I have other projects that I have to focus on for income, but I will say that I expect it to be within a reasonable time frame and that the rewrite has seen significant progress recently.

1 Like

Are you able to add a feature where you can preview what it’ll look like before you generate the arc? This can work with the slider that’s already supported and it’ll update with the preview smoothly.

This would be like those games where you pull a bow and arrow and you can see where it’s gonna land and adjust your camera correctly. Thanks!

1 Like

May I ask,

Are you still working on Archimedes 4? If yes,
When is the release of Archimedes 4?
How far through Archimedes 4 are you currently?
What will Archimedes 4 include?

Does anyone know if you can use different parts? Let’s say I want different parts to go not the same exact one. Is that in the paid version? I might want part 1 2 times, then texture it with part 2, part 1 again, part 3 or maybe a part 4.

I’m curious about the calculation method used to create curved or rotating parts within this plugin. It seems that the standard mathematical equations, such as the typical 360-degree rotation for a full circle, are not applicable here. Instead, the angle tabs appear to max out at 100. Could you please provide insight into how the angle count works?

I have zero idea how math work by the way