Knuckle Cracker

Particle Fleet => Map Makers, Ship Builders, and Coders => Topic started by: kajacx on November 25, 2016, 03:00:02 PM

Title: How exactly are custom ships encoded to PRPL data?
Post by: kajacx on November 25, 2016, 03:00:02 PM
I want to create a map where players can create their custom ships by merging their other ships. This is possible thanks to the "AddCustomShipToInventory" PRPL method, that takes a base64-encoded string containing ship info (the very same string generated by pressing the "PRPL data to clipboard" button in ship editor) and adds that ship to your ship pool.

EDIT: I have already solved this problem, look at my replies below for explanation and yes, PRPL code as well.
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: mirror corparation on November 26, 2016, 09:42:01 AM
3F in hexadecimal is 63, 40 in hexadecimal = 64 and 41 in hexadecimal is 65. might help you
EDIT: converted all your numbers
1 - 128 63
2 - 000 64
3 - 064 64
4 - 224 64
5 - 000 65
6 - 001 65
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: kajacx on November 26, 2016, 01:55:44 PM
EDIT: Now includes the new ship info (author & description) from version 1.1.4.

After 2 days of testing, I have finally figured everything out.

General overview:
Spoiler

By hitting the "PRPL Data to Clipboard" in editor, you get a base-64 encoded string containing all the info on how to construct the ship. This is how the data looks like for the CRUISER built-in ship: (I rebuild the Cruiser ship in editor, so the order of the modules might be different)

New version for 1.1.4
Spoiler

(http://i.imgur.com/31bDP40.png)
[close]

Old version (if you find the new one too confusing)
Spoiler

(http://image.prntscr.com/image/67f1e0e3e19e4ca2b363557e3f85b986.png)
[close]

All the grey parts are always the same for each ship.
All the numbers are in Little Endian format (the least significant bytes are on the left, so for example 7 becomes "07 00 00 00" and not "00 00 00 07") (except in the "module data" section, where the triplet (moduleID, xPosition, yPosition) is encoded as float, so it creates a wierd pattern).
For example, width "0B 00 00 00" means the width is 11.
[close]

Module Data:
Spoiler

Each module on the ship (except the command module) gets exactly 12 bytes in the "module data" section, which look like this:
00 00 MM MM 00 00 XX XX 00 00 YY YY
where X any Y are coordinates of the module, and M is the module ID.

Module ID table:

ENGINE          A0 40
LATHE           10 41
LASER           00 40
CANNON          80 3F
MISSLE_LAUNCHER 40 40
PARTICLE_BEAM   80 40
DISCHARGE       90 41
ENERGY_TANK     C0 40
PORT            00 41
GUPPY           E0 41
SHIELD          40 41
REACTOR         60 41
FIGHTER_BASE    20 41
GRABBER         80 41
MK7             88 41


The position of a module is the distance from it's left-bottom corner to the left-bottom corner of your ship.
In other words, consieder your module in the most left-bottom corner of your ship. Now move your module x cells to the right and y cells up. Congratulation, you have a module at position x,y. But don't think it will be that easy, since this position is not stored in the data itself, but rather some bizzare values are. Here is a complete list of such values for each distace/position:


00: 00 00
01: 80 3F
02: 00 40
03: 40 40
04: 80 40
05: A0 40
06: C0 40
07: E0 40
08: 00 41
09: 10 41
10: 20 41
11: 30 41
12: 40 41
13: 50 41
14: 60 41
15: 70 41
16: 80 41
17: 88 41
18: 90 41
19: 98 41
20: A0 41
21: A8 41
22: B0 41
23: B8 41
24: C0 41
25: C8 41
26: D0 41
27: D8 41
28: E0 41
29: E8 41
30: F0 41
31: F8 41
32: 00 42
33: 04 42
34: 08 42


The number on the left is the distance you want, and the 2 numbers on the right are the 2 bytes that you need to write to the "module data" section to have your module at that position. Note: someone correctly pointed out that is a conversion from an integer to the IEEE short floating point standard, great observation, I wouldn't have seen it otherwise.

Example:
Spoiler

(http://image.prntscr.com/image/9da8274d5a0749909f9d3c1d7d7cfe81.png)

Here, the green square is at the position 0,0 - the most left-bottom position of the ship. The engine (the yellow square) is at position 1,3 because it is one cell to the right and three cells to the top from the 0,0 left-bottom corner of your ship.

Summary: you have an Engine, at position 1,3. Now you look up the code for engine ("A0 40"), position 1 ("80 3F") and position 3 ("40 40"), so the final values is:
00 00 A0 40 00 00 80 3F 00 00 40 40

This is exactly the first 12 bytes of the "module data" section in the example above.
[close]

Convert each module to the 12 bytes as shown in the example, and then simply put them all in the "module data" section. The command module is not stored here.
[close]

Hull info:
Spoiler

The hull is described simply by a list of all hull parts. The part list is here:
(http://image.prntscr.com/image/09e176d388984f81b7f7d1a1447321cf.png)

After the complete size of the hull (even with empty spaces, so width * height, brown color in overview), just put code for each block (even empty ones), starting from left-bottom, and then goining left-to-right, and then bottom-to-top once you reach the end of each row.
[close]

The rest of the stuff:
Spoiler

The rest should be pretty obivous from the overview, I'll just remind you that all numbers are in 4 bytes little endian format (even in "hull info" section), except in "module data" section, where everything is wierd, and in the "ship's name's length" section, that only contains the lower 2 bytes of the ship's name's length.

The postion of the command module is handled similiary to other modules, it's distance from the left-bottom corner is in the "X/Y position of the center", this time it is the acctual distance, and not some random number like in the "module data" section.
[close]

Well, that's all I have for now, I'll be adding some PRPL code that acctually does all this stuff once I get around to write it, expect method signature similar to this
String construct(int width, int height, int[] hull, List<Module> modules, int centerX, int centerY, String name)
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: planetfall on November 26, 2016, 05:19:51 PM
So, when I was a kid, there was this tetris-clone-ish thing on my computer, which was one of those paleolithic Apple affairs of translucent gray and blue plastic. I don't remember much about the game except there were cones in the background for some reason, and eyeball blocks, and occasionally if you managed to do something sufficiently badass you would hear this dude say "IMPRESSIVE" in an incredibly deep, resounding voice that echoed once or twice. That specific sound effect is my response to the above post.
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: TonnyT on November 26, 2016, 11:37:36 PM
I wish there was a upvote system so I could upvote this.
Instead I shall have to offer my praise and commentary.

Well done, very well done indeed.
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: kajacx on November 27, 2016, 10:42:48 AM
Update: the PRPL script now includes the ship description info from version 1.1.4. Also I have re-writen the script to PRPL+, my custom extension of PRPL (https://knucklecracker.com/forums/index.php?topic=22809.0), but don't worry, the compiled PRPL code is in the zip as well.
I will not update the Java file, since I no longer have all the code in one single file. You can however see the ShipConstruct (https://github.com/kajacx/PRPL-Plus/blob/master/src/com/prplplus/shipconstruct/ShipConstructor.java) class from my custom ship editor if you are interested in the source code. (End of update)

Thanks for support, I have managed (at least I think) to make it work in PRPL, I'm too tired now to properly document the API, but just look at the "constructLathe" example, it should be pretty clear from there.

I'm adding the Java code that I used as well, if anyone is interested.
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: Nicant on November 27, 2016, 11:05:49 AM
Woah, looking at those scripts i wonder if it is possible to make an adaptive ship that gets smarter each time it gets destroyed!
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: Sorrontis on November 27, 2016, 11:24:58 AM
This.... is.... amazing!

I wonder if there's a way to modify a ship once it's already built...
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: kajacx on November 27, 2016, 11:47:37 AM
Quote from: Sorrontis on November 27, 2016, 11:24:58 AM
I wonder if there's a way to modify a ship once it's already built...

You could probably destroy your ship and replace it with a new one. Next weekend I'll do merging of ships, and also post the code, so changing ships with it shouldn't be that difficult.
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: GoodMorning on November 30, 2016, 04:43:56 AM
Interesting. A little bit of PRPL, and an enemy which gains a module for each ship it destroys on respawn...

Or a one-shot custom ship which you must collect parts of, before building, and cannot be reconstructed.
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: GoodMorning on December 04, 2016, 06:46:26 AM
The thought occurs that with this knowledge, you might be able to stack modules by malformed data.

Time to build the most impressive (and expensive) 7x7 ship possible. You never thought that you could stack fifty shield modules, did you?
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: kajacx on December 06, 2016, 01:13:02 PM
QuoteTime to build the most impressive (and expensive) 7x7 ship possible. You never thought that you could stack fifty shield modules, did you?

(https://i.imgflip.com/1fgjq6.jpg)

I'm sorry I had to. I just had to.
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: uncopy2002 on December 29, 2016, 06:22:51 PM
QuoteModule ID table:
ENGINE          A0 40
LATHE           10 41
LASER           00 40
CANNON          80 3F
MISSLE_LAUNCHER 40 40
PARTICLE_BEAM   80 40
DISCHARGE       90 41
ENERGY_TANK     C0 40
PORT            00 41
GUPPY           E0 41
SHIELD          40 41
REACTOR         60 41
FIGHTER_BASE    20 41
GRABBER         80 41
MK7             88 41


00: 00 00
01: 80 3F
02: 00 40
03: 40 40
04: 80 40
05: A0 40
06: C0 40
07: E0 40
08: 00 41
09: 10 41
10: 20 41
11: 30 41
12: 40 41
13: 50 41
14: 60 41
15: 70 41
16: 80 41
17: 88 41
18: 90 41
19: 98 41
20: A0 41
21: A8 41
22: B0 41
23: B8 41
24: C0 41
25: C8 41
26: D0 41
27: D8 41
28: E0 41
29: E8 41
30: F0 41
31: F8 41
32: 00 42
33: 04 42
34: 08 42

Uhm, my first reaction from seeing a 00 00 08 3F is that they're floating point numbers. For floating points numbers, 00 00 08 3F = 3F80000 = 1.0. So for some reasons module IDs are in float? Though for the coordinates it really makes sense since the game itself uses float for the positions (so everything don't move in steps of 1, always snapping to the grid).

There should be float to integer type conversion tool online, but I prefer using Cheat Engine to do this.
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: kajacx on January 02, 2017, 11:47:35 AM
Nice observation. I have noticed a pattern in how the numbers are increased, and have extrapolated that pattern to fit the first 128 positions (with success). Only later I have noticed it's acctually being cast to float, and I had the biggest facepalm ever.
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: tornado on February 14, 2017, 12:41:54 PM
Quote from: kajacx on November 27, 2016, 11:47:37 AM
Quote from: Sorrontis on November 27, 2016, 11:24:58 AM
I wonder if there's a way to modify a ship once it's already built...

You could probably destroy your ship and replace it with a new one. Next weekend I'll do merging of ships, and also post the code, so changing ships with it shouldn't be that difficult.

This is something ive wondered about too(ship that consumes smaller enemy ships?).
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: kajacx on February 23, 2017, 08:30:30 AM
Just for fun, this is what happens when your coding goes horribly wrong.

Casual 4 HQs
(http://i.imgur.com/RQr1JLR.png)
[close]
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: Keeper Decagon on February 23, 2017, 09:14:09 AM
Quote from: kajacx on February 23, 2017, 08:30:30 AM
Just for fun, this is what happens when your coding goes horribly wrong.

Casual 4 HQs
(http://i.imgur.com/RQr1JLR.png)
[close]

Haha, this can also be done without coding. Simply click on the normal HQ, open the ships tab (in editor), then click "Add Ship to Inventory" a few times.

Just thought I'd share that little tidbit.
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: kajacx on February 23, 2017, 09:30:02 AM
Quote from: Keeper Decagon on February 23, 2017, 09:14:09 AM
Haha, this can also be done without coding. Simply click on the normal HQ, open the ships tab (in editor), then click "Add Ship to Inventory" a few times.

LOL, you can even move the big blue command module around, I'll definitely find out how to put that on custom ships, it's gonna be great. It seems like a special module that isn't avaliable in the editor (nothing interesting there), but doesn't collide with other modules when you place it.

This could lead to people creating custom HQ's for their maps, thanks for the tip.
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: Dark Ambition on February 23, 2017, 09:39:30 AM
Quote from: kajacx on February 23, 2017, 09:30:02 AM
This could lead to people creating custom HQ's for their maps, thanks for the tip.

Waaaaaayyyyyy ahead of you :P
Spoiler
http://knucklecracker.com/forums/index.php?topic=23192.msg155645#msg155645

http://knucklecracker.com/forums/index.php?topic=23181.msg155634#msg155634

http://knucklecracker.com/forums/index.php?topic=23214.msg155667#msg155667

http://knucklecracker.com/forums/index.php?topic=23213.msg155666#msg155666

http://knucklecracker.com/forums/index.php?topic=23212.msg155665#msg155665

http://knucklecracker.com/forums/index.php?topic=23776.msg157080#msg157080
[close]
Title: Re: How exactly are custom ships encoded to PRPL data?
Post by: kajacx on February 28, 2017, 12:43:21 PM
Quote from: Dark Ambition on February 23, 2017, 09:39:30 AM
Waaaaaayyyyyy ahead of you :P

Cool, but does any of your ships have 4 HQs? :D
4 HQs insta-building ship (http://knucklecracker.com/forums/index.php?topic=24001.0)
Image
(http://knucklecracker.com/particlefleet/queryShips.php?query=thumbnailid&id=709)
[close]

If you are wondering how on Earth did I do this, check out my Custom ship builder (http://knucklecracker.com/forums/index.php?topic=22706.0) (shameless self-promotion FTW), I'll upload version 0.1.3 later tonight where you will be able to do this as well.