Plus Porter (1.1.0.1)

Jan 28, 2015 at 8:14 PM
Lvl 1
Forum Moderator
"Life begins and ends with Nu."
Join Date: May 28, 2008
Location: PMMM MMO
Posts: 3713
Age: 32
Okay Hayden, I think you're going to have to explain to me how TestMatch terminates, since from examining the code you've posted, it should just enter an infinite recursive loop (is this the full code for that function??).
 
Jan 28, 2015 at 8:47 PM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
Pronouns: he/him
Have you considered that the problem you're trying to solve is not actually necessary?
A diff image meets the needs of being able to distribute modified content without publishing the entirety of the original data files. Small re-uses such as the cases you've outlined above are really not a concern; nobody is going to pirate CS+ by having 3 tiles from PrtSand in a mod.
And besides, your algorithm isn't infalliable either. What if I just reduce the lightness on all the channels in an image by 1? The colors will be "Different", but the content will be the same.
As for rearranging assets and using assets from different images or whatever, I really doubt anybody would ever go to all the trouble of making that work on a non-trivial scale, just to circumvent your program and compile a bogus mod full of "ripped" content. If they wanted to do that, they could just bundle it together manually anyway.

As well, I can't even figure out how your recursive function is supposed to terminate.

Your method is elaborate but really the only impact I see is:
- requiring shit-tons of RAM due to your crazy algorithm
- increasing the length of the port process dramatically
- inflating the disk space used by orders of magnitude

The goal of the software should be to make the modding process easier on both the developer and the player by automatically cleaning up the majority of unchanged content. I think you've over-solved the issue.
 
Jan 28, 2015 at 11:03 PM
Based Member
"Life begins and ends with Nu."
Join Date: Dec 31, 2011
Location: United States
Posts: 2326
Age: 28
Pronouns: he/him
Okay Hayden, I think you're going to have to explain to me how TestMatch terminates, since from examining the code you've posted, it should just enter an infinite recursive loop (is this the full code for that function??).
As well, I can't even figure out how your recursive function is supposed to terminate.
Again, that was a condensed version of the algorithm; pasting the whole thing would have had a bunch of extra stuff (such as references to some global variables) that would have distracted from the main commands. It ignores pixels that don't match, pixels that have already been visited, pixels that have already been linked, or pixels that the algorithm has been told to ignore, which ensures that the algorithm will sooner or later encounter a dead end and terminate. If you really want to see the full algorithm, though, then here it is:
Code:
private static void TestMatch(BufferedImage image1, BufferedImage image2, int x1, int y1, int x2, int y2, boolean source)
{
    if(source)
    {
        minX = image1.getWidth()-1;
        minY = image1.getHeight()-1;
        maxX = 0;
        maxY = 0;
        tempVisitedPixels2 = new boolean [image2.getHeight()][image2.getWidth()];
        semiRecordedPoints = new ArrayList<String>();
        differentColors = new ArrayList<Color>();
        notQuiteRecorded = new boolean[image1.getHeight()][image1.getWidth()];
    }
    if( ( ((x1 >= 0 && y1 >= 0) && (x2 >= 0 && y2 >= 0)) && (x1 <= image1.getWidth()-1 && x2 <= image2.getWidth()-1)) && ((y1 <= image1.getHeight()-1) && (y2 <= image2.getHeight()-1)) )
    {
        if((tempVisitedPixels2[y2][x2] == false && blankPixels2[y2][x2] == false) && (linkedPixels[y1][x1] == false && tempBlankPixels1[y1][x1] == false))
        {
            if(new Color(image1.getRGB(x1, y1)).equals(new Color(image2.getRGB(x2, y2))))
            {
                if(differentColors.indexOf(new Color(image1.getRGB(x1, y1))) == -1)
                    differentColors.add(new Color(image1.getRGB(x1, y1)));
                if(x1 < minX)
                    minX = x1;
                if(y1 < minY)
                    minY = y1;
                if(x1 > maxX)
                    maxX = x1;
                if(y1 > maxY)
                    maxY = y1;
                tempVisitedPixels2[y2][x2] = true;
                semiRecordedPoints.add("(" + String.valueOf(x1) + "," + String.valueOf(y1) + ") = (" + String.valueOf(x2) + "," + String.valueOf(y2) + ")");
                notQuiteRecorded[y1][x1] = true;
                displayPanel.repaint();
                TestMatch(image1, image2, x1 + 1, y1, x2 + 1, y2, false);
                TestMatch(image1, image2, x1 + 1, y1 + 1, x2 + 1, y2 + 1, false);
                TestMatch(image1, image2, x1, y1 + 1, x2, y2 + 1, false);
                TestMatch(image1, image2, x1 - 1, y1 + 1, x2 - 1, y2 + 1, false);
                TestMatch(image1, image2, x1 - 1, y1, x2 - 1, y2, false);
                TestMatch(image1, image2, x1 - 1, y1 - 1, x2 - 1, y2 - 1, false);
                TestMatch(image1, image2, x1, y1 - 1, x2, y2 - 1, false);
                TestMatch(image1, image2, x1 + 1, y1 - 1, x2 + 1, y2 - 1, false);
            }
        }
        tempVisitedPixels2[y2][x2] = true;
        if(source)
        {
            boolean sufficient;
            if(differentColors.size() < 3)
                sufficient = false;
            else if(differentColors.size() == 3)
                sufficient = (semiRecordedPoints.size() >= 45);
            else if(differentColors.size() == 4)
                sufficient = (semiRecordedPoints.size() >= 22);
            else if(differentColors.size() == 5)
                sufficient = (semiRecordedPoints.size() >= 15);
            else //(differentColors.size() >= 6)
                sufficient = (semiRecordedPoints.size()*differentColors.size() >= 40);
            if(sufficient)
            {
                checkBlobs = true;
                for(int i = 0; i < semiRecordedPoints.size(); i++)
                {
                    linkedPixels[Integer.parseInt(semiRecordedPoints.get(i).substring(semiRecordedPoints.get(i).indexOf(",")+1,
                    semiRecordedPoints.get(i).indexOf(")")))][Integer.parseInt(semiRecordedPoints.get(i).substring(1, semiRecordedPoints.get(i).indexOf(",")))] = true;

                    linkedPixel[Integer.parseInt(semiRecordedPoints.get(i).substring(semiRecordedPoints.get(i).indexOf(",")+1,
                    semiRecordedPoints.get(i).indexOf(")")))][Integer.parseInt(semiRecordedPoints.get(i).substring(1, semiRecordedPoints.get(i).indexOf(",")))]
                    = semiRecordedPoints.get(i).substring(semiRecordedPoints.get(i).indexOf("=")+2);
					
                    linkedPixels2[Integer.parseInt(semiRecordedPoints.get(i).substring(nthOccurrence(semiRecordedPoints.get(i), (char)(44), 1)+1,
                    semiRecordedPoints.get(i).length()-1))] [Integer.parseInt(semiRecordedPoints.get(i).substring(nthOccurrence(semiRecordedPoints.get(i),
                    (char)(40), 1)+1, nthOccurrence(semiRecordedPoints.get(i), (char)(44), 1)))] = true;
                    numberOfLinkedPixels++;
                }
            }
        }
    }
}

Have you considered that the problem you're trying to solve is not actually necessary?
A diff image meets the needs of being able to distribute modified content without publishing the entirety of the original data files. Small re-uses such as the cases you've outlined above are really not a concern; nobody is going to pirate CS+ by having 3 tiles from PrtSand in a mod.
Back when you had that page up on your blog which outlined the circumstances under which one could apply for your 2x resolution hack, you sternly stated that no mod could use NICALiS' graphics, be it in whole or in part. I've been under the impression since then that distributing anything that contains recognizable excerpts of NICALiS graphics is frowned upon at best. What you say about 3 tiles not mattering does make sense though, since taking a port down for that reason would be a bit gestapo. Sure, the examples I gave would hardly be worth taking action against, but what if someone made a port with significantly more copyrighted graphics present? Exactly where do we draw the line? If there's any medium on which the answer to a question of legal or illegal will be left up to personal interpretation, then it's not something I want to involve myself with.


And besides, your algorithm isn't infalliable either. What if I just reduce the lightness on all the channels in an image by 1? The colors will be "Different", but the content will be the same.
Point taken.

As for rearranging assets and using assets from different images or whatever, I really doubt anybody would ever go to all the trouble of making that work on a non-trivial scale, just to circumvent your program and compile a bogus mod full of "ripped" content. If they wanted to do that, they could just bundle it together manually anyway.
If I were to use an algorithm like yours, I wouldn't be nearly as afraid of people maliciously distributing too much copyrighted content as I would be of people unwittingly doing so.

Your method is elaborate but really the only impact I see is:
- requiring shit-tons of RAM due to your crazy algorithm
- increasing the length of the port process dramatically
- inflating the disk space used by orders of magnitude
The goal of the software should be to make the modding process easier on both the developer and the player by automatically cleaning up the majority of unchanged content. I think you've over-solved the issue.
You are absolutely right. The problem is that I can't bring myself to climb into the boat of thinking that distributing portions of NICALiS' graphics is okay when doing so in larger portions would be indisputably illegal. If you can think of something else to say that might convince me otherwise, though, then I will definitely consider rewriting the graphics filtering algorithm to be simpler.
 
Jan 30, 2015 at 12:39 AM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6225
Age: 39
Pronouns: he/him
Noxid said:
Can you give me a counter-case to this algorithm
Note the following:
modded.getHeight()
modded.getWidth()
canon.getWidth()
canon.getHeight()

The values for these never change yet you recalculate those same values over and over again thousands upon thousands of times. This is poor code. You should save all four values to variables before the loop even starts so that they only need to be calculated once.
 
Jan 30, 2015 at 12:47 AM
In my body, in my head
Forum Moderator
"Life begins and ends with Nu."
Join Date: Aug 28, 2009
Location: The Purple Zone
Posts: 5998
Pronouns: he/him
The implementation of those calls is not a part of the scope of my algorithm however I am pretty sure the value is calculated on image load and returned via a simple getter.
I mean yeah it's some overhead but I wasn't really aiming for flawless code in my example, I just threw it together...
 
Jan 30, 2015 at 10:32 PM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6225
Age: 39
Pronouns: he/him
HaydenStudios said:
The reason your algorithm wouldn't work in all cases is because it makes 2 assumptions:
1) It assumes that it will only need to scan 1 image in order to get all of the copyrighted content out of it
2) It assumes that all of the copyrighted content in the image being filtered is at the exact same location as the one being scanned

In order to find all the copyrighted graphics in all cases, it has to scan all of the images in the Cave Story+ installation, and anticipate that any part of the image being filtered could be any part of an existing NICALiS image.

I'm open to hearing ways that I can make my code better, but first I want to make sure you fully understand how complex the problem is. I'm getting the impression that neither you nor GIR have tried Plus Porter out. If you're this interested in helping me optimize my code (which I appreciate that you are, by the way), taking the program out for a spin yourself would probably go a long way towards helping you understand exactly what you're trying to help me optimize.
Create a resource that lists the first four non-black colours in a 16x16 square (don't list pure black sections) from nicalis' resources tied to a list of ids that represent bmp files. Hell you could create a binary file that stores this date in 16 byte blocks, or hey, 32 byte blocks if you want to include the coordinates for that 16x16 block. Create a tool to do the job for you, don't do it by hand. Now you only need to check a few files for the sprite rather than all of them.
 
Jan 31, 2015 at 2:09 AM
Based Member
"Life begins and ends with Nu."
Join Date: Dec 31, 2011
Location: United States
Posts: 2326
Age: 28
Pronouns: he/him
andwhyisit said:
Create a resource that lists the first four non-black colours in a 16x16 square (don't list pure black sections) from nicalis' resources tied to a list of ids that represent bmp files. Hell you could create a binary file that stores this date in 16 byte blocks, or hey, 32 byte blocks if you want to include the coordinates for that 16x16 block. Create a tool to do the job for you, don't do it by hand. Now you only need to check a few files for the sprite rather than all of them.
I kind of already have one of the steps in my algorithm take measures to ensure it won't waste its time thoroughly scanning images that aren't likely to contain matches. Before it begins the scanning process, it evaluates the colors present in both images, and skips the image to scan if the two images have fewer than 2 colors in common. This works pretty effectively in ruling out most images. If you load an image, you'll most likely notice that you visually see it compare the image to a few of NICALiS' images, and then when it's done, the "xx" in the "scanning image xx of 109" part of the graphics filtering window title goes up rapidly because it's passing through most images.
 
Jan 31, 2015 at 6:18 AM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6225
Age: 39
Pronouns: he/him
HaydenStudios said:
I kind of already have one of the steps in my algorithm take measures to ensure it won't waste its time thoroughly scanning images that aren't likely to contain matches. Before it begins the scanning process, it evaluates the colors present in both images, and skips the image to scan if the two images have fewer than 2 colors in common. This works pretty effectively in ruling out most images. If you load an image, you'll most likely notice that you visually see it compare the image to a few of NICALiS' images, and then when it's done, the "xx" in the "scanning image xx of 109" part of the graphics filtering window title goes up rapidly because it's passing through most images.
So do you do this before reading any images? Or is this after? If it is after then I think your checks aren't doing enough.

Actually, scratch my earlier suggestion. Instead of storing rgb values for the first 3 pixels of Nicalis' graphics I would store checksums of the rgb values of all pixels in that block. I would recommend checking differences per 16x16 block. Then compare the checksums of differing blocks with the checksums in the binary. If you find a match then you can load the file and check directly.

4 bytes: Checksum of RGB values (for all pixels within the block)
1 byte: Resource ID (that represents the .bmp file)
1 byte: Horizontal position in blocks (a block being 16 pixels)
1 byte: Vertical position in blocks
1 byte: Keep reading status (1 means there is another block that shares the same checksum recorded later in the file than this one, 0 means to stop searching and that this is the last occurrence of this checksum in the file)

To generate the checksum multiply the red green and blue values of each pixel together and add the resulting values together for all pixels in that 16x16 block.

(r1*g1*b1)+(r2*g2*b2)+...+(r255*g255*b255)+(r256*g256*b256)

The resulting checksum should always fit within 4 bytes of data. With over 4.2 billion possible combinations it would be hard to end up with any two blocks with matching checksums unless they actually matched.

These 8 bytes will repeat for every single 16x16 block (except pure black ones). That means that you will have 8 bytes for every single block of every single image that you may never need to load. That's 760 bytes less image data to be loaded into ram per block, and best of all you don't ever need to search for the block in question, the information you need is right there.

Once again you will need to write a tool to generate this file for you.

The point is to be able to check these files without ever loading them into memory and without ever needing to search them at all.

Of course that means that you will be comparing whole blocks for externally sourced graphics, but that should be enough. And you should still be able to compare individual pixels for differences on the sheet in question.
 
Feb 1, 2015 at 9:11 PM
Based Member
"Life begins and ends with Nu."
Join Date: Dec 31, 2011
Location: United States
Posts: 2326
Age: 28
Pronouns: he/him
andwhyisit said:
So do you do this before reading any images? Or is this after?
I perform this filter after loading the images.

andwhyisit said:
If it is after then I think your checks aren't doing enough.

Actually, scratch my earlier suggestion. Instead of storing rgb values for the first 3 pixels of Nicalis' graphics I would store checksums of the rgb values of all pixels in that block. I would recommend checking differences per 16x16 block. Then compare the checksums of differing blocks with the checksums in the binary. If you find a match then you can load the file and check directly.

4 bytes: Checksum of RGB values (for all pixels within the block)
1 byte: Resource ID (that represents the .bmp file)
1 byte: Horizontal position in blocks (a block being 16 pixels)
1 byte: Vertical position in blocks
1 byte: Keep reading status (1 means there is another block that shares the same checksum recorded later in the file than this one, 0 means to stop searching and that this is the last occurrence of this checksum in the file)

To generate the checksum multiply the red green and blue values of each pixel together and add the resulting values together for all pixels in that 16x16 block.

(r1*g1*b1)+(r2*g2*b2)+...+(r255*g255*b255)+(r256*g256*b256)

The resulting checksum should always fit within 4 bytes of data. With over 4.2 billion possible combinations it would be hard to end up with any two blocks with matching checksums unless they actually matched.

These 8 bytes will repeat for every single 16x16 block (except pure black ones). That means that you will have 8 bytes for every single block of every single image that you may never need to load. That's 760 bytes less image data to be loaded into ram per block, and best of all you don't ever need to search for the block in question, the information you need is right there.

Once again you will need to write a tool to generate this file for you.

The point is to be able to check these files without ever loading them into memory and without ever needing to search them at all.

Of course that means that you will be comparing whole blocks for externally sourced graphics, but that should be enough. And you should still be able to compare individual pixels for differences on the sheet in question.
Your technique is very clever, and far less demanding than what I've written, and it would even pretty much work on the two examples I showed Noxid; however, I can still think of some practical cases where it would miss some NICALiS graphics. The problem is that, while the precise position of the NICALiS content doesn't matter for your algorithm, it still needs to be snapped to a 16x16 grid like all of the unmodified sprites in order for your technique to work, and it needs to not be "overlayed" onto something else. Here are two examples that exploit this:

This here is the modified "casts.bmp" from my fourth ending mod. Pretend that it's double resolution:
casts_zps0z1hkf1w.png

Notice the human Sue and Itoh in the second to last row. Everything in that Image would be no problem detecting, until you leave only the human Sue and Itoh. Itoh's sprite in that image is not snapped to the same grid that his sprite is in the NpcGuest spritesheet. In which case, the checksums for the 16x16 blocks will be representing different areas of Itoh, which is likely to yield a different combination of pixels, which in effect is likely to give 2 checksums of the same sprite that don't match, which would likely make the algorithm skip over that part.


For the other example, here is the modified "PrtStore.bmp" from my fourth ending mod. Again, pretend it's double resolution:
PrtStore_zpsc6g2832n.png

Notice the human Sue and Itoh in the bottom row of tiles. In this case, their sprites are overlayed on top of tiles from the tileset. Even if Sue and Itoh were properly snapped to the 16x16 grid, the checksums for the tiles of the human Sue and Itoh sprites wouldn't find a match with any from the NpcGuest spritesheet since there would be extra pixels surrounding them which would likely generate non-matching checksums.


In summary, despite being able to deal with more cases than Noxid's suggestion, your suggestion still falls short of my needs due to relying on all sprites to be snapped to a specified grid, and lacks the ability to "trace around" the copyrighted imagery in the event that other pixels are in close proximity to the NICALiS sprite.

I really appreciate the feedback and suggestions that you guys are giving, and I hope that I don't come off as arrogant or close-minded by turning down your ideas; I just don't see them as properly substituting what I currently have in place.
 
Feb 2, 2015 at 1:31 PM
Administrator
Forum Administrator
"Life begins and ends with Nu."
Join Date: Jul 15, 2007
Location: Australia
Posts: 6225
Age: 39
Pronouns: he/him
I don't know if I can write this to be less confusing, but here goes...

casts.bmp needs its own logic.

For casts.bmp you should work with 48x48 blocks and for each differing block imagine a 33x33 area on the top-left corner. I shall call this area the traversal box. Traverse each pixel in that box and use each pixel as a starting point (top-left corner) for a 16x16 block that you calculate a checksum from.

In order to do this more efficiently... Well lets look at an example.

We are traversing one pixel to the right. Create a checksum of the pixels being removed by themselves and then the pixels being added. Then you can subtract the removal pixels checksum from the original checksum and add the adding pixels checksum to get the new checksum as a result while only needing to query a small number of rgb values. Record the top row's 33 checksums. You can then use these values to repeat this feat vertically.

By the end of it all you should have checksummed every possible 16x16 box in that 48x48 diff block.

If you do get a positive checksum then grid out rightwards and downwards from there within the 48x48 box to search for other matches.

For the second example I would use the old logic to reverse check Nicalis' NpcGuest.bmp and NpcRegu.bmp (and only those files) against the output of the diff check, but only for files that contain NpcGuest and NpcRegu colours only in their diff sections (you should track this as you go). The majority of possible overlays I can think of that may actually matter should be in those files.

In the end this one concession would still be 50x less expensive than what you are doing now.

Although now things have become significantly more complex.

EDIT: If you read this post prior to this edit then I buggered up the box sizes, if so then please read it again.
 
Feb 18, 2015 at 11:34 PM
Based Member
"Life begins and ends with Nu."
Join Date: Dec 31, 2011
Location: United States
Posts: 2326
Age: 28
Pronouns: he/him
So, I've been thinking this over.

At this point you've piqued my interest enough for me to decide that I'll try to incorporate your idea into Plus Porter and see if I can make the filtering process go smoother. Though I do think it may be a little bit too optimistic to think that custom spritesheets that contain NICALiS content overlayed onto something else will only be from NpcRegu and NpcGuest, because there are some other candidates from the Npc folder that may have sprites pulled from it like that. And the more exceptions like this that need to be made, the less valuable your technique becomes. Still, the standard and tileset images make up a good portion of things, and those are extremely unlikely to need this exception to be made. I'll have to see how this translates to actual code to really determine if it works like I want it to.

Thank you very much for the feedback.
 
Mar 14, 2015 at 9:14 PM
Neophyte Member
"Fresh from the Bakery"
Join Date: Mar 14, 2015
Location:
Posts: 3
Hi. I'm trying to use Plus Porter to install your Fourth Ending mod, which I just learned about today.

I downloaded 1.0.5.0, and placed the folder inside my Cave Story+ installation, for easy access. However, the program does not respond to many things that I click on. I can get into the menus for "Manage Ports", "Preferences", and everything under "Help" works, and I can start a "New Port". However, after a New Port is started, I cannot cancel or save the new port, and I have to close the program. Clicking "Open Port" does nothing, so I can't install the mod.

Opening the CS+ directory actually worked once, but only once, and I can no longer change it (not that I need to). Now clicking on "Open CS+ directory" does not function, neither does clicking "Browse" to change it through the Preferences menu.

I have tried moving the program to different locations, restarting my computer, updating my version of Java, and using past versions of Plus Porter, to no avail. I am using Windows 7 64-bit.

Based on the Readme, I don't think I did anything wrong. Has this happened to anyone before? Is there anything I can do that you could think of? Obviously this is a problem on my end, not with the program itself.

This is a screenshot of what I see when I start Plus Port:
why.png

Any help would be great, thanks.
 
Mar 14, 2015 at 10:38 PM
Based Member
"Life begins and ends with Nu."
Join Date: Dec 31, 2011
Location: United States
Posts: 2326
Age: 28
Pronouns: he/him
Given the number of people that have reported this same issue, I'm pretty sure that it's actually my fault this is happening due to the way I coded something. I've had a suspicion as to what the problem is for a little while, but I'm not quite sure. Try using this slightly modified version of the latest build, and tell me if it behaves any better.
 
Mar 15, 2015 at 1:13 AM
Based Member
"Life begins and ends with Nu."
Join Date: Dec 31, 2011
Location: United States
Posts: 2326
Age: 28
Pronouns: he/him
Well, this is becoming all the more frustrating. Like I've said to others who've had this problem, try creating a text document in the same folder as the Plus Porter exe, and fill it with this:

Code:
java -jar "PlusPorter.exe"
Then rename it to a .bat file and run it. This should make a command window pop up along with the program. What's supposed to happen is that the program should behave the same as before, but with the console window telling you what's wrong when you get an error. What's happened instead for everyone else who's tried this is that it mysteriously fixes it. This is nice on a case-by-case basis, but it's unfortunately prevented me from being able to get to the bottom of this issue. But try this anyway and tell me what happens.
 
Mar 15, 2015 at 2:43 AM
Neophyte Member
"Fresh from the Bakery"
Join Date: Mar 14, 2015
Location:
Posts: 3
That certainly did fix all of my problems. Thanks for the fix. Is there anything from the debugging window you want me to send to you? Or anything else you want that could help you?
 
Mar 15, 2015 at 5:26 AM
beep boop
Bobomb says: "I need a hug!"
Join Date: Aug 16, 2014
Location: no
Posts: 848
Age: 23
Pronouns: he/him
Maybe you could do that to the porter, and distribute that instead? Or will it only work when run on the computer that shows the error.
 
Mar 20, 2015 at 3:38 PM
Senior Member
"I, Ikachan. The Life and Documentary of the OrigiNAL SQuiD."
Join Date: Jul 21, 2012
Location: Valley of the Fallen Star
Posts: 176
Age: 26
Pronouns: he/him
I finally got around to trying this, and I had a similar issue to Horribly. Plus Porter sometimes didn't allow me to choose the CS+ Directory or open a specific mod file. Given multiple attempts, it did eventually work. I was able to get the fourth ending mod to run.
However, when I tried to port AGTP Story, I kept getting errors. Following what you said above, I was able to receive this in the command window.
When I first loaded the mod up, it gave me a warning saying that entering any map higher than 95 would crash the game. There are exactly 95 maps in the AGTP mod.
 
Mar 22, 2015 at 12:39 AM
Based Member
"Life begins and ends with Nu."
Join Date: Dec 31, 2011
Location: United States
Posts: 2326
Age: 28
Pronouns: he/him
Sorry not replying sooner, I've been busy.


Bionicobot said:
Maybe you could do that to the porter, and distribute that instead? Or will it only work when run on the computer that shows the error.
That is an option I'm considering, but I really think it would be preferable to figure out what problem is occurring and fixing it by changing the code.

Rubyyoshi said:
I tried to port AGTP Story, I kept getting errors. Following what you said above, I was able to receive this in the command window.
When I first loaded the mod up, it gave me a warning saying that entering any map higher than 95 would crash the game. There are exactly 95 maps in the AGTP mod.
Ah, that is an error with the port of AGTP Story itself, and not with Plus Porter. That port was made with an earlier version of Plus Porter that I think put some unnecessary garbage in the stage.tbl file that doesn't play well with newer versions. I've been meaning to put up a different download, so thanks for reminding me. The download for AGTP Story has been updated to fix this.



As for those menu options not working, I would like to try something. HorriblyUnoriginal, Rubyyoshi, or anyone who's had the issue of the Open port, Open CS+ Directory, or any browse buttons not working, please try out this debugged version of Plus Porter and tell me what happens. You should get a series of message boxes followed by the browsing window, followed by one more message. And please do this without the console window open, because that tends to make this error hide from us.
 
Mar 23, 2015 at 12:35 AM
Senior Member
"I, Ikachan. The Life and Documentary of the OrigiNAL SQuiD."
Join Date: Jul 21, 2012
Location: Valley of the Fallen Star
Posts: 176
Age: 26
Pronouns: he/him
With the updated AGTP Story and the debugged version, it seemed to work much smoother (It didn't get hung-up at all). The only thing that happened, is that the message box went to 6 before it gave the option to browse for the directory or mod, then said 7 and then opened it.
Another thing that occurred, but wasn't too bad, was the patching speed on the fourth ending mod. In the debugged version, it was longer than the original version of plus porter 1.0.5.0. In the end, it was applied successfully.
 
Back
Top