CMPGenerator

Feb 27, 2018 at 7:31 AM
Senior Member
Modding Community Discord Moderator
CSE Discord Moderator
"I, Ikachan. The Life and Documentary of the OrigiNAL SQuiD."
Join Date: Jan 14, 2014
Location: Antarctica (The Penguins say Hi)
Posts: 150
Age: 24
This has been out on the CSMC for a bit now, but I figured the forums would probably like a link.
CMPGenerator is a modding tool that aims to make the process of creating large CMP/SMP TSC commands easy.

It's 99% feature complete right now, with the last 1% being a few extra options/quality of life improvements.
The program's pretty simple to use (and should be Mac/Linux compatible thanks to Mono), but if you want some sort of a tutorial, feel free to read this quick guide:
Currently, CMPGenerator works off of .pxm files directly, so before you begin, make sure you know what the actual file names of your maps are.

  1. Start the program and click "File" -> "Open" -> "Map 1...".
  2. Select the map file you would like to use as a base, then select the tileset that belongs to it (or one that doesn't, if you like glitches).
  3. Unless you plan on turning this map (or a portion of it) into another separate map, you can click "Yes" to loading this map as map two. Otherwise, it's the same map opening process as last time.
  4. Now that you have your maps opened, make some edits! None of these changes are saved to the .pxm file unless you manually click "Save As..." and overwrite, so feel free to mess up either map as much as you want.
  5. As you make changes, CMPGenerator will automatically generate a long string of CMP/SMP commands that turn map one into map two. In the event it doesn't, just click "Regenerate" under "TSC Options".
  6. Copy/Paste the tsc into your editor of choice. In the event your game crashes on loading the map, try using the "tsc_malloc" xml in boosters lab's hackinator.

  • By default, CMPGenerator will not generate any CMP/SMP code for tiles that don't need any change. This can be changed by unchecking "Ignore Identical Tiles" in the main CMPGenerator window.
  • As I mentioned in Getting Started, CMPGenerator can load two completely separate maps if you so desire. Doing so does not account for anything but the tile data however, so it's up to you to account for differences in the tileset.
  • Each map has an adjustable rectangle overlayed on top of it called the "range", which determines what tiles are actually being considered for CMP/SMP generation. It can be adjusted using the "Range Editor".
  • Map one's range can either be as big as map one, or as big as map two's range, while map two's range has no limit (No, that doesn't mean you can have the range be outside the map boundaries).
  • In the event map one and map two's ranges' are not the same size, CMPGenerator will automatically generate the appropriate OOB TSC flags to resize the map.
  • Depending on how you resize the map, Cave Story may end up pulling tile data out of ram. To simulate this, CMPGenerator has a bunch of different map importing options (which can be found in each map's "Open..." menu), and makes use of a feature called a "null tile". Null tiles represent tiles whose values will be pulled from RAM at runtime, and so can not be easily predicted. You can place these manually, but their main purpose is for use with those custom import options (in the event you do know what map was previously loaded/what tiles will be there).
  • Having null tiles in either range will disable use of SMP.
  • If you already have some CMP/SMP/OOB TSC flags you would like to apply to a map (maybe you're adding on to a previous set of CMP/SMP commands), just click "Apply TSC", paste in your code, and hit "Ok".
 
Feb 27, 2018 at 1:30 PM
Based Member
"Life begins and ends with Nu."
Join Date: Dec 31, 2011
Location: United States
Posts: 2307
Age: 27
Hey, this is a really neat concept! I actually envisioned a tool like this a while ago, but never got around to making it, so I'm glad someone's working at it.

It looks like there are some bugs that still need to be worked out, though. I tried to load the blcny1 with prtWhite, and it only showed me the upper region of the map, and didn't seem to let me scroll. I then tried to load the core room instead, and accepted the offer to load a new tileset as well, and loaded prtAlmond. The result seemed to be a garbled room that had the layout of the core room but the tileset of prtWhite. When I checked what tileset was loaded by checking "View" -> "Tileset", it showed the prtWhite tileset with prtAlmond overlaid onto the upper region of the tileset. After I had these garbled maps, no other map that I tried to load would show up right.

I restarted the program after this, and I was able to load up the Egg Corridor okay, except it still wouldn't let me scroll to the farther right regions of the map. After applying some changes to the map, I tried to do "Edit" -> "Apply TSC", and a window with a blank text box appeared, and then I clicked "Ok" on that window, and then I got an error message. It told me that an unhandled exception has occurred, and that I could continue and have it ignore the error, or I could quit the application. The exact error was "Object reference not set to an instance of an object." It allowed me to expand the details to give me more information about the error. I've pasted those details it here:
See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.

************** Exception Text **************
System.NullReferenceException: Object reference not set to an instance of an object.
at CMPGenerator.FormMap.applyTSCToolStripMenuItem_Click(Object sender, EventArgs e)
at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met)
at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ToolStrip.WndProc(Message& m)
at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)


************** Loaded Assemblies **************
mscorlib
Assembly Version: 4.0.0.0
Win32 Version: 4.7.2563.0 built by: NET471REL1
CodeBase: file:///C:/Windows/Microsoft.NET/Framework/v4.0.30319/mscorlib.dll
----------------------------------------
CMPGenerator
Assembly Version: 1.0.0.0
Win32 Version: 1.0.0.0
CodeBase: file:///C:/Program%20Files/Pixel/modding%20tools/CMPGenerator.exe
----------------------------------------
System.Windows.Forms
Assembly Version: 4.0.0.0
Win32 Version: 4.7.2558.0 built by: NET471REL1
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Windows.Forms/v4.0_4.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System
Assembly Version: 4.0.0.0
Win32 Version: 4.7.2558.0 built by: NET471REL1
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System/v4.0_4.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Drawing
Assembly Version: 4.0.0.0
Win32 Version: 4.7.2558.0 built by: NET471REL1
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Drawing/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System.Configuration
Assembly Version: 4.0.0.0
Win32 Version: 4.7.2558.0 built by: NET471REL1
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Configuration/v4.0_4.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Core
Assembly Version: 4.0.0.0
Win32 Version: 4.7.2563.0 built by: NET471REL1
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Core/v4.0_4.0.0.0__b77a5c561934e089/System.Core.dll
----------------------------------------
System.Xml
Assembly Version: 4.0.0.0
Win32 Version: 4.7.2612.0 built by: NET471REL1LAST_B
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/System.Xml/v4.0_4.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
ObservableCollectionEx
Assembly Version: 1.4.0.0
Win32 Version: 1.0.0.0
CodeBase: file:///C:/Program%20Files/Pixel/modding%20tools/CMPGenerator.exe
----------------------------------------
WindowsBase
Assembly Version: 4.0.0.0
Win32 Version: 4.7.2563.0 built by: NET471REL1
CodeBase: file:///C:/Windows/Microsoft.Net/assembly/GAC_MSIL/WindowsBase/v4.0_4.0.0.0__31bf3856ad364e35/WindowsBase.dll
----------------------------------------

************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.

For example:

<configuration>
<system.windows.forms jitDebugging="true" />
</configuration>

When JIT debugging is enabled, any unhandled exception
will be sent to the JIT debugger registered on the computer
rather than be handled by this dialog box.

Sometimes when I'm loading up a new map, I get a little pop-up window with the title "MapImporter" with some options about resizing, or some NullAndAppend option, and I'm not quite sure what the purpose of that window is.

I like the concept, but this could do with some more testing. I'll be happy to give this another try when it's a bit more polished.
 
Last edited:
Feb 27, 2018 at 2:28 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
This seems like it would make a lot more sense to pair with a custom command that's more suited to the task. In hacker story i wrote a custom command to copy map chunks.
Or if you're using cmp so much maybe consider just making another map? Would be easier to manage imo
 
Feb 27, 2018 at 2:48 PM
Based Member
"Life begins and ends with Nu."
Join Date: Dec 31, 2011
Location: United States
Posts: 2307
Age: 27
Or if you're using cmp so much maybe consider just making another map? Would be easier to manage imo
That's an option, but sometimes when you're porting a mod, you need to downsize the number of maps. Plus if you don't want to do any <TRAs and just want stuff to change in real-time, this could be useful. For example, I bet Shmitz would have liked to have had a tool like this back when he made that area in Jenka's Nightmare where the platforms <CMP into existence as you advance through the level. As another idea, I think it would be really cool to see a mod that has a map that morphs in real time on a larger scale, that's something I've never seen before that this would make easier.
 
Feb 27, 2018 at 4:23 PM
Eevee Enthusiast
"Big Joe Tire and Battery Restaurant! Opening Soon! Eat at Big Joes!"
Join Date: Mar 26, 2014
Location: Somewhere with Wi-Fi
Posts: 541
Age: 26
This seems like it would make a lot more sense to pair with a custom command that's more suited to the task. In hacker story i wrote a custom command to copy map chunks.
Or if you're using cmp so much maybe consider just making another map? Would be easier to manage imo
What if you want to pull an Ordeal Pillar and reveal the map one layer of tiles at a time?
Granted, I did move those transitions to separate maps to make sure I didn't go over the TSC limit.
 
Feb 27, 2018 at 4:29 PM
Senior Member
Modding Community Discord Moderator
CSE Discord Moderator
"I, Ikachan. The Life and Documentary of the OrigiNAL SQuiD."
Join Date: Jan 14, 2014
Location: Antarctica (The Penguins say Hi)
Posts: 150
Age: 24
@HaydenStudios
  • The map not scrolling is "intentional", as in I never actually added a feature to let you scroll through the map. In the meantime, you can zoom the map by using ctrl+scroll wheel (and the window should be resizable if it's going off the edges).
  • That thing with Apply TSC... that's just me being dumb and forgetting to check for null as an input; will put out a patch soon.
  • The tileset loading behavior is intended, since (fun fact) that's what's actually happening when you load another map in CS, it just pastes the new map's tileset over the old one. I'm not so sure that the "all further maps being garbled" thing is intentional though... I'll have to look into it.
  • I'll add a thing explaining the MapImporter in the advanced section soon (though reading the section on "null tiles" will get you started).
 
Feb 27, 2018 at 4:30 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
Custom commands again, tbh
 
Feb 27, 2018 at 7:04 PM
Based Member
"Life begins and ends with Nu."
Join Date: Dec 31, 2011
Location: United States
Posts: 2307
Age: 27
Custom commands again, tbh
At the end of the day, though, there's a deep satisfaction that one can feel by accomplishing something like this via <TSC alone with no assembly editing. Just ask EnlightenedOne who did all kinds of weird things with flags, or Carrotlord who programmed a money system with just flags. It also maintains the portability of a mod to MAC, PSP, and CS+.
 
Last edited:
Feb 27, 2018 at 10:33 PM
ZYZZ Spur is the best gun because its super cool
"All your forum are belong to us!"
Join Date: Jan 15, 2017
Location: Northern Hemisphere
Posts: 564
Age: 16
wait is this a thing so that if you want to make a big change in the map you don't have to do that <CMP thing for every tile

that'd be neato if it was
 
Feb 28, 2018 at 1:17 AM
Based Member
"Life begins and ends with Nu."
Join Date: Dec 31, 2011
Location: United States
Posts: 2307
Age: 27
wait is this a thing so that if you want to make a big change in the map you don't have to do that <CMP thing for every tile

that'd be neato if it was
Technically you do still have to have a <CMP command for every tile you want to change, it's just that this tool automatically generates the script for that for you.
 
Feb 28, 2018 at 2:50 AM
ZYZZ Spur is the best gun because its super cool
"All your forum are belong to us!"
Join Date: Jan 15, 2017
Location: Northern Hemisphere
Posts: 564
Age: 16
I'm going to miss having to do that...
i dont do it even if i have a good idea to do something big with the cmp things

Technically you do still have to have a <CMP command for every tile you want to change, it's just that this tool automatically generates the script for that for you.
isn't that like the right click when in the tile mode in boosters lab
 
Feb 28, 2018 at 2:46 PM
Based Member
"Life begins and ends with Nu."
Join Date: Dec 31, 2011
Location: United States
Posts: 2307
Age: 27
isn't that like the right click when in the tile mode in boosters lab
More or less, except I'm only aware of that tool's ability to do one tile at a time. I'm not aware of any BL feature that helps you make changes en masse.
 
Feb 28, 2018 at 9:21 PM
The TideWalker
Modding Community Discord Founder
"That dog!"
Join Date: Apr 5, 2013
Location: In my mind and of my body.
Posts: 1640
Age: 26
At the end of the day, though, there's a deep satisfaction that one can feel by accomplishing something like this via <TSC alone with no assembly editing. Just ask EnlightenedOne who did all kinds of weird things with flags, or Carrotlord who programmed a money system with just flags. It also maintains the portability of a mod to MAC, PSP, and CS+.

Not using assembly for the sake of not using assembly is bad.
There is no novelty of not digging into an arbitrary chunk of code and changing the binary values of an .exe. This kind of thinking really irritates me because this mindsets makes it so that people are willing to put up with "not quite good enough" or "less effective and takes more time". This is 2018, the Cave Story Modding Community has made great strides in many area to make assembly easier to get into, and to make what is considered basic things that should already be accessible to a game for modding, do-able. (Such as weapon editing and the 50 some XML's that Enlight has made for the Haxinator)

Enlight did make the OOB flag chart, but it's a harder version of <HEX because you have to start at the beginning of the flag data and count up instead of just putting in your offset and writing the data. Less effective time wise, more complicated and you can't (at least as far as I know) get to every singe byte in the exe using thsi method so people would just go without.

I'm not aware of Carrotlord's money hack using flags, but if you're referring to his hack that was a broken TSC command and a 7 line hack that gave you one money each time you touched an EXP shard (instead of 5 or 20 depending on size of the shard) that was very incomplete because there was no HUD, or a <SEL command (that by the way I made recently with all these features mentioned above as well as the exp shard being separate from the money npc if you want it to. .)

I get the notion that less is more but is far beyond it. Doing <CMP 10 trillion times is not honourable, it's just wasteful. And while Bray doesn't have a perfect solution to the TSC limit, or otherwise; It's nice to see that he's trying to make something that overall helps people with modding by removing all this time put into nothing more than monotonus BS and redirecting it to making new characters and new weapons better maps, better dialouge, and better mods.

All this stuck up novelty, and split of ASM vs no ASM is just something I'm rather sick of and it definitively needs to go. Look at ROM hacking, they have to use asm all the time and it's a lot harder to do because code is optimized among many other things. Assembly isn't hard or scary for CS, there are plenty of people around now that can and will teach people who are willing to put the time in to learn it. It's not 2008 anymore that was 10 years ago. Let's get the ball rolling and stop this nonsense of not touching the exe because it's sacred or something equally dumb.

To better levels, stories, art, music... mods; and better modders.
 
Feb 28, 2018 at 9:25 PM
Deliverer of Sweets
Bobomb says: "I need a hug!"
Join Date: Jul 20, 2015
Location: Under sea level or something
Posts: 785
Age: 25
Or how about we just, you know, stop caring about wether ASM is used or not instead of hunting people for wether they do or not.
 
Feb 28, 2018 at 9:38 PM
The TideWalker
Modding Community Discord Founder
"That dog!"
Join Date: Apr 5, 2013
Location: In my mind and of my body.
Posts: 1640
Age: 26
I want to very clearly state that I do NOT care if ASM is used, but saying the bogeyman is attached to assembly is something I will not take. Especially with all the resources available for assembly to make it easy to use now. People are should use what makes them the most effective as a modder. If it's assembly great. if not that's fine as well. I just want a strong stance saying that assembly is not an evil. Not that people who do not use it are evil.
 
Feb 28, 2018 at 9:46 PM
Deliverer of Sweets
Bobomb says: "I need a hug!"
Join Date: Jul 20, 2015
Location: Under sea level or something
Posts: 785
Age: 25
Yeah see, I very much agree that people should do what they're good at, and shouldn't be nudged towards either ASM or TSC other than that I generally wouldn't recommend getting too deep into ASM if you are a first timer on modding.
What I eventually care about is wether a mod is good or not, not on how it's made.
 
Feb 28, 2018 at 9:49 PM
The TideWalker
Modding Community Discord Founder
"That dog!"
Join Date: Apr 5, 2013
Location: In my mind and of my body.
Posts: 1640
Age: 26
So you would very much agree with the statement that "Not using assembly for the sake of not using assembly is bad." correct?

I feel like you're interjecting into the conversation with a single statement trying diverge this into a "nobody should care" argument.
 
Feb 28, 2018 at 9:59 PM
Deliverer of Sweets
Bobomb says: "I need a hug!"
Join Date: Jul 20, 2015
Location: Under sea level or something
Posts: 785
Age: 25
So you would very much agree with the statement that "Not using assembly for the sake of not using assembly is bad." correct?
Generally not really actually. Unless it's done with the intent to taunt avid ASM users.
Challenging yourself to avoid ASM can be a fun puzzle sometimes and there can be some clever looking solutions at times.
 
Top