Starblast Wiki
Explore
Main Page
All Pages
Interactive Maps
navigation
Main page
Community portal
Recent changes
Random page
Admin noticeboard
Official Website
Starblast.io
About the game
How to play
Modes
Ships
Upgrades
Strategies
Changelogs
Custom Games
ECP
Game support
Gamepedia
Gamepedia support
Report a bad ad
Help Wiki
Contact us
FANDOM
Fan Central
BETA
Games
Anime
Movies
TV
Video
Wikis
Explore Wikis
Community Central
Start a Wiki
Don't have an account?
Register
Sign In
Sign In
Register
Starblast Wiki
694
pages
Explore
Main Page
All Pages
Interactive Maps
navigation
Main page
Community portal
Recent changes
Random page
Admin noticeboard
Official Website
Starblast.io
About the game
How to play
Modes
Ships
Upgrades
Strategies
Changelogs
Custom Games
ECP
Game support
Gamepedia
Gamepedia support
Report a bad ad
Help Wiki
Contact us
Editing
Advanced Ship Editing
Back to page
Edit
VisualEditor
View history
Talk (0)
Edit Page
Advanced Ship Editing
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
Before looking at this thread, it is recommended that you have first looked at the original [[Ship Editor Tutorial]] and are well familiarized with the Ship Editor. === Introduction === Before we delve into the power of CoffeeScript, we need to make a slight change to how we call our model first (not needed for few limited power like array extensions).<br /> Instead of <code>return model =</code> at the beginning of the ship code, we will simply change that to <code>model =</code> and at the very end of the ship code we will put <code>return model;</code>. This won't affect how we normally use the ship editor and simply allows for extra code to work after the ship code. As a reminder, here are all available properties of the ship structures (bodies / wings / tori): <syntaxhighlight lang="coffeescript"> bodies: [body_name]: section_segments: n #or [n...array.length] required offset: #required with children x: n y: n z: n position: #required with children x: [n...array.length] y: [n...array.length] z: [n...array.length] width: [n...array.length] #required height: [n...array.length] #required texture: n #or [n...array.length] optional angle: n #optional vertical: true/false #optional propeller: true/false #optional laser: #optional with required children damage: [min,max] rate: n speed: [min,max] number: n angle: n #optional type: n #optional error: n #optional recoil: n #optional wings: [wing_name]: doubleside: true/false offset: #required with children x: n y: n z: n length: [n...array.length] #required width: [n...array.length] #required angle: [n...array.length] #required position: [n...array.length] #required texture: n #or [n...array.length] optional bump: #optional with required children position: n size: n tori: [torus_name]: radius: n #required segments: n #or [n...array.length] required section_segments: n #or [n...array.length] required offset: #required with children x: n y: n z: n position: #required with children x: [n...array.length] y: [n...array.length] z: [n...array.length] width: [n...array.length] #required height: [n...array.length] #required texture: n #or [n...array.length] optional </syntaxhighlight> === Reset Points === Reset points allow us to start a new object from the same body (well, technically not but at least appear to).<br /> A reset point is when 2 joints next to each other in the width & height arrays are 0. The location of these 2 joints however will be in different places, giving the illusion of starting another object elsewhere from the same body. (In reality, the object draws an invisible 0 width and height line between the two joints.)<br /> For example: <syntaxhighlight lang="coffeescript"> spikes: section_segments: 4 offset: x: 0 y: 0 z: 0 position: x: [-10,-18,-18,-15,-24,-24,-20,-32,-32] y: [-30,20,20,-23,30,30,-12,40,40] z: [0,0,0,0,0,0,0,0,0] width: [0,1.5,0,0,1.5,0,0,2,0] height: [0,1,0,0,1,0,0,1,0] texture: [1] </syntaxhighlight> Here's a more extreme example of using reset points in this construction pylon. Yes, this is all one body. [[File:unknown.png|400px]] === Functions === Functions are prepared blocks of code that sit before our ship code, which can then be called later on. For our purposes, we will be using them to make bodies.<br /> To create a function, all we need is the name of the function followed by brackets, and then the magic <code>-></code> and there's your function.<br /> It should look something like this: <syntaxhighlight lang="coffeescript"> myFunction = () -> </syntaxhighlight> But right now it has no use.<br /> So lets start by making it create a body for us. For this example I will be using a simple ring generator function, but before we do, I will post useful array extensions in which the function partly relies on.<br /> Credit for these array extensions go out to [[User:123 Notus|123 Notus]]. <syntaxhighlight lang="coffeescript"> Array::add = (mod) -> @map (val) -> val + mod Array::mult = (mod) -> @map (val) -> val * mod Array::div = (mod) -> @map (val) -> val / mod Array::step = (step) -> i for i in @ by step Array::refill = (val, len) -> val for i in ( if len? then [0...len] else if @length == 1 then [0...@[0]] else @ ) for key of Array:: Object.defineProperty Array::, key, enumerable: false </syntaxhighlight> The top block of code are the functions themselves, but due to an error in Ship Editor, the mod export will not work. This is where the fix comes in the second block. We use them after arrays as follows: <syntaxhighlight lang="coffeescript"> [array.length].add(n) [array.length].mult(n) [array.length].div(n) [array.length].step(n) [array.length].refill(n) </syntaxhighlight> More details can be found there: [https://gist.github.com/123-Notus/01f71ef57d3955dbd5d829ad80e2abe8 Array extending in Starblast Ship Editor]. Back to our function: <syntaxhighlight lang="coffeescript"> ringGen = (xx, yy, zz, segments, length, width, thick, thicc, vert, tx, angle) -> return k = section_segments: segments offset: x: xx y: yy z: zz position: x: [0,0,0,0,0,0,0,0,0,0,0,0,0] y: [-2.25,2.25,2.25,-2.25,-2.25].mult(thick+thicc) z: [0,0,0,0,0,0,0,0,0,0,0,0,0] width: [width+2.5*thick,width+2.5*thick,width-2.5*thick,width-2.5*thick,width+2.5*thick] height: [length+2.5*thick,length+2.5*thick,length-2.5*thick,length-2.5*thick,length+2.5*thick] vertical: vert texture: tx angle: angle </syntaxhighlight> As we can see, the function now has internal variables assigned to it which we have mapped to the corresponding properties of our body. We call it under bodies in our ship code as follows: <syntaxhighlight lang="coffeescript"> mainEnginering1: ringGen(0,40,0,8,14,14,1,0.5,false,[17,4,17,4],0) </syntaxhighlight> And it should look something like this: [[File:Screenshot_2.png|400px]] Functions like this are useful for creating complex bodies. It means we can just take a pre-existing base and call it from 1 line rather than manually create the whole thing many times to where the code takes 500 lines worth of bodies and all their properties. It should be noted that functions don't need to be this complex. It's entirely possible to simply use it for mass duplication of bodies with the necessary control using the function parameters. It's also useful if we decide that we want to change something that all of these bodies have in common. We can do so by changing the body properties in the function itself and all of the bodies called from the function will update, rather than having to change every one individually.<br /> So as useful as this is, we can go further. I want my functions to be able to create not 1, but several bodies. For this, we're going to have to do something slightly different.<br /> Instead of using <code>return k =</code> which allows us to call the function alongside the bodies of our ship code, we will be using what is called <code>model.bodies</code> which will let us pre-specify our body names using strings. <syntaxhighlight lang="coffeescript"> model.bodies['bodyName' + n] = </syntaxhighlight> Note that I've also included <code>+ n</code> for this case, it's important that we avoid duplicate names because the code cannot differentiate 2 different objects with the same name, even with different properties. So the best solution for this is to number these bodies by adding n in the function parameters. This will let us manually number them, but we still need to be careful that we don't end up with duplicate numbers. This becomes especially important when we get to loop functions. I want to put turrets on my ships. So lets do that using a 3 body function. <syntaxhighlight lang="coffeescript"> addDualGun = (n, xpos, ypos, zpos, size, angle, dmg, rt, spd, nmbr) -> model.bodies['quadTurret'+n] = section_segments: 8 offset: x: xpos y: ypos z: zpos position: x: [0,0,0,0,0,0,0,0,0,0].mult(size) y: [-22,-21,-16,-14,-14,14,14,16,21,22].mult(size) z: [0,0,0,0,0,0,0,0,0,0].mult(size) width: [0,10,15,15,12,12,15,15,10,0].mult(size) height: [0,6,12,12,9,9,12,12,6,0].mult(size) texture: [17,4,17,4,4,4,17,4,17] vertical: false angle: 90+angle model.bodies['gunBarrel1'+n] = section_segments: 8 offset: x: xpos y: ypos z: zpos position: x: [0,0,0,0,0,0,0,0].add(-9*size) y: [-50,-50,-43,-43,-25,-25,0,0].mult(size) z: [0,0,0,0,0,0,0,0].add(6*size) width: [0,2,2,1,1,3,3,0].mult(size) height: [0,2,2,1,1,3,3,0].mult(size) texture: [17,4,4,2,4,4,4] angle: angle laser: damage: dmg rate: rt speed: spd number: nmbr model.bodies['gunBarrel3'+n] = section_segments: 8 offset: x: xpos y: ypos z: zpos position: x: [0,0,0,0,0,0,0,0].add(9*size) y: [-50,-50,-43,-43,-25,-25,0,0].mult(size) z: [0,0,0,0,0,0,0,0].add(6*size) width: [0,2,2,1,1,3,3,0].mult(size) height: [0,2,2,1,1,3,3,0].mult(size) texture: [17,4,4,2,4,4,4] angle: angle laser: damage: dmg rate: rt speed: spd number: nmbr </syntaxhighlight> To call this function, rather than call it under bodies in our ship code, we instead have to call it after our ship code. <syntaxhighlight lang="coffeescript"> addDualGun(0,50,0,0,1,-90,[8,12],2,[120,150],1) return model; </syntaxhighlight> [[File:Screenshot_3.png|400px]] We can take this to extremes as we see fit, however I cannot stress enough the importance of keeping code like this optimised as much as possible. Highly detailed, 1 pixel in game is absolutely unnecessary and only wastes server resources. In other words, be careful when calling a lot of functions like this. The poly-count adds up faster than you think. === for-loops === <code>for</code> loops allow you to iterate over bits of code. Essentially, it generates an array. You can use it like this for specific numbers <syntaxhighlight lang="coffeescript"> for i in [0,-18,16,50+x,-75*y] </syntaxhighlight> But the most useful way is to use it like this <syntaxhighlight lang="coffeescript"> for i in [0..8] # this will generate [0,1,2,3,4,5,6,7,8] for i in [0...8] # this will generate [0,1,2,3,4,5,6,7] </syntaxhighlight> 2 dots will generate the array between the 2 values, including both values. 3 dots will generate the array but without the last number. You can also use it like this for multiples of 2 <syntaxhighlight lang="coffeescript"> for i in [0..8] by 2 # this will generate [0,2,4,6,8] for i in [0...8] by 2 # this will generate [0,2,4,6] for i in [0..7] by 2 # this will still generate [0,2,4,6] because 7 is outside the possible integers by 2 </syntaxhighlight> For our case, we will be using for loops to iterate over bodies, again using model.bodies. The previous image example showing our turrets from our function was actually using a for loop. <syntaxhighlight lang="coffeescript"> for i in [0...4] model.bodies['sideBits'+i] = section_segments: [45,135,225,315] offset: x: 93 y: i*43-49 z: -12 position: x: [0,0,0,0,6,6,0,0,0,0].mult(0.8) y: [-25,-25,-20,-15,-15,15,15,20,25,25].mult(0.8) z: [0,-2,0,0,-8,-8,0,0,-2,0].mult(0.8) width: [0,18,18,12,5,5,12,18,18,0].mult(0.8) height: [0,17,20,20,6,6,20,20,17,0].mult(0.8) texture: [4] angle: 0 addDualGun(i,96,i*43-49,-10,0.5,-90,[8,12],2,[120,150],1) </syntaxhighlight> Notice how <code>i</code> is used and multiplied to spread their distances. And yes, it's entirely possible to use loops to iterate over laser properties. Here's another example where we generate an array of cubes <syntaxhighlight lang="coffeescript"> for i in [0..10] model.bodies['emitter'+i] = section_segments: [45,135,225,315] offset: x: i*100 y: 0 z: 0 position: x: [0,0,0,0] y: [-2,-2,2,2] z: [0,0,0,0] width: [0,3,3,0] height: [0,3,3,0] texture: [0] </syntaxhighlight> [[File:Screenshot_4.png|400px]] Oh and did I mention we can nest loops to generate a grid? <syntaxhighlight lang="coffeescript"> for i in [0..10] for j in [-10..10] model.bodies['emitter'+i+'node'+j] = section_segments: [45,135,225,315] offset: x: i*100 y: j*100 z: 0 position: x: [0,0,0,0] y: [-2,-2,2,2] z: [0,0,0,0] width: [0,3,3,0] height: [0,3,3,0] texture: [0] </syntaxhighlight> [[File:Screenshot_5.png|400px]] Oh, no. We're not done yet. <syntaxhighlight lang="coffeescript"> for i in [0..10] for j in [-10..10] for k in [-10..10] model.bodies['emitter'+i+'node'+j+'height'+k] = section_segments: [45,135,225,315] offset: x: i*100 y: j*100 z: k*100 position: x: [0,0,0,0] y: [-2,-2,2,2] z: [0,0,0,0] width: [0,3,3,0] height: [0,3,3,0] texture: [0] laser: # because I can damage: [2000,2000] rate: 0.0166666666666666666666667 speed: [100,100] number: 16 angle: 360-(360/16) </syntaxhighlight> [[File:Screenshot_6.png|400px]] Alright that's enough madness. But seriously though, be careful when trying this, it will most likely lag. === Conclusion === There's just one final note I would like to put out there. The ship editor was never expected/meant to be used to such an advanced level, so to those programmers out there who are feeling creative, don't expect much as the ship editor comes as it is. Everything here uses the same fundamentals as the original tutorial, just in a different way that takes off a good amount of manual work. The most important thing to remember in ship building is to remain open and creative. Highly detailed ships are good and all, but don't go overboard with bodies. Make good use of the available textures, as limited as they may be, because they compensate for large, flat areas that lack detail. It's completely fine to use several bodies to construct a detailed part of a ship. Just make sure they're not just a pixel big in game, otherwise they become unnoticed and obsolete. But most importantly of all, experiment, have fun and create complete garbage ships. Because that's how you will learn and improve. The ship editor is more than just capable of building ships, which the most talented ship builders Finalizer & Goldman & Uranus have proven. == See Also == === Tutorials === * [[Ship Editor Tutorial]] * [[Modding Tutorial]] === Tools === * [https://starblast.io/shipeditor/ Ship Editor] * [https://starblast.io/modding.html Mod Editor] * [https://bhpsngum.github.io/starblast/mapeditor/ Map Editor] (by community)
Summary:
Please note that all contributions to the Starblast Wiki are considered to be released under the CC BY-NC-SA
Cancel
Editing help
(opens in new window)
Follow on IG
TikTok
Join Fan Lab