Outpost Universe Forums

Projects & Development => Projects => Topic started by: TechCor on November 13, 2019, 07:05:26 AM

Title: OP2 Mission Editor
Post by: TechCor on November 13, 2019, 07:05:26 AM
Hey there!

Welcome to another episode of TechCor's OP2 Projects!

Today, we are going to focus on the Outpost 2 Mission Editor.

This top post will be edited as development progresses - just like the C# Mission SDK.

Releases
https://github.com/TechCor8/OP2MissionEditor/releases (https://github.com/TechCor8/OP2MissionEditor/releases)

Source
Mission Editor: https://github.com/TechCor8/OP2MissionEditor (https://github.com/TechCor8/OP2MissionEditor)
OP2Utility.NET: https://github.com/TechCor8/OP2UtilityDotNet (https://github.com/TechCor8/OP2UtilityDotNet)


Currently designing the feature set for this project. Additional details in the following post.
Title: Re: OP2 Mission Editor
Post by: TechCor on November 13, 2019, 07:07:34 AM
Tools:
This project is going to be built with Unity since I have a lot of experience working with it. It will make long-term maintenance a pain (annual upgrades), but it shouldn't take more than a few hours each year to update. It will be very important not to let the project rot to the point of being unsalvagable.

The editor's missions will work exclusively with the C# Mission SDK through the use of its JSON data files. There will be an extra feature to export the MAP portion through OP2 Utility, but for the most part, data will be saved in JSON. For devs that prefer to work in C++, don't forget you can link to the C# SDK and continue working in C++.

Feature Specification:
Code: [Select]
--------
Menu bar
--------
File:
New
Open...
Import Map...
Save
Save As...
Export Map...
Exit

Edit:
Map Properties
Mission Properties
Player Properties

--------------
Map Properties
--------------
Width
Height

------------------
Mission Properties
------------------
Description
MapName
TechTreeName
MissionType (DropDown)
MaxTechLevel (DropDown)
UnitOnlyMission (Checkbox)

DaylightEverywhere (Checkbox)
DaylightMoves (Require DaylightEverywhere=false, Checkbox)
InitialLightLevel (int inputfield)

Music Playlist
Scroll list of tracks
Add track (dropdown)
Remove track
Move up/down
Repeat start index

-----------------
Player Properties
-----------------
Scroll list of players
Add Player
Remove Player

TechLevel
MoraleLevel
FreeMorale
ColonyType (dropdown: Eden, Plymouth)
IsHuman (checkbox)
BotType (dropdown)
Color (dropdown)
Allies: Togglable scroll list of players
Center View X
Center View Y

Kids
Workers
Scientists
CommonOre
RareOre
Food
SolarSatellites

Scroll list of completed research
Add topic (dropdown: Data pulled from tech file)
Remove topic


----------
Paint Pane
----------
Dropdown (Terrain, CellTypes, Resources, Walls and Tubes, Disasters, Units, Structures, Locations)

Terrain:
Tiles (Extract BMP)

CellTypes:
CellType (dropdown)

Resources:
Prebaked Icon
Common Mining Beacon
Rare Mining Beacon
- Yield (dropdown)
- Variant (dropdown)
- *Spawn Area (width/height)

Fumarole
- *Spawn Area

Magma Vent
- *Spawn Area

Circle Marker
DNA Marker
- *Spawn Area

Wreckage:
- Type (dropdown: spaceship parts)
- IsVisible (checkbox)
- *Spawn Area

Walls and Tubes:
Prebaked Icon
Tube
Wall
Lava Wall
Microbe Wall

Disasters:
DisasterType (dropdown)
*SrcArea
*DestArea
Size
Duration
StartTime
EndTime
MinDelay
MaxDelay
(If disaster has both src and dest areas, must place both for disaster area to appear)

--NOTE--
*Areas are painted by clicking and dragging to create the size

Units/Structures:
Colony (dropdown: Eden, Plymouth)
Prebaked Icon
Direction
CargoType (dropdown: Convec=StructureKit, Truck=TruckCargo) Must be convec or truck
CargoAmount (int inputfield, cargo truck only)

Locations: (Used for triggers)
ID (alphanumeric?)
*Spawn Area

--------
Triggers
--------
TBD

-------------------
AI Base Preplanning
-------------------
TBD

Please let me know if you have any feature requests or changes you would like to see, and also if you see any problems with the current list.
Title: Re: OP2 Mission Editor
Post by: Hooman on November 13, 2019, 10:11:06 AM
Slightly related, I had a project I was working on a while back that converted the Outpost 2 map file to JSON format. Not sure it would be useful to you though. It mostly just made use of OP2Utility, which you can use directly.

Would be good to have extra map data stored in JSON format, rather than forcing people to write executable DLL code.
Title: Re: OP2 Mission Editor
Post by: Vagabond on November 15, 2019, 08:31:26 PM
techcor,

This sounds ambitious. Good Luck! I would be willing to do some light testing for you if it gets far enough along.

We should talk about your use cases for the sprites contained in Outpost 2. Currently, OP2Utility will just extract individual frames. You will probably want to show composite frames of structures. I wanted to program this, but wasn't good enough at the bitmap format at the time. I could take another look at it though if you think it would be helpful.

At any rate, please report any bugs are wanted features in OP2Utility. I'll see what I can do to accommodate the changes.

----

Hooman, if your ideas are fairly well fleshed out, maybe it would be good to get it in the repo so techcor can use it?

-Brett
Title: Re: OP2 Mission Editor
Post by: Hooman on November 15, 2019, 10:26:23 PM
I'll have to dig up the project and upload it to GitHub.



Actually, I was just thinking, a C# project that could run with Mono would work on Linux. That would be wonderful. The current OP2 editor doesn't run on Linux, and trying to update it so it does sounds like a rather difficult undertaking.
Title: Re: OP2 Mission Editor
Post by: TechCor on November 16, 2019, 11:48:37 AM
Just committed OP2Utility.NET's source to GitHub.

Unity can build to Linux, so the editor will work there as long as an ".so" can be built from the OP2UtilityForC project in OP2Utility.NET. Someone will need to check that source out and see if they can make an .so. No rush though, OP2UtilityForC has not been tested yet.

----

The editor has the menu options set up. Going to add the code behind them later tonight now that I have OP2 Utility for C#.
Title: Re: OP2 Mission Editor
Post by: Hooman on November 17, 2019, 07:26:45 AM
For those who are curious, the link to the project is:
https://github.com/TechCor8/OP2UtilityDotNet (https://github.com/TechCor8/OP2UtilityDotNet)

Edit: Ahh, I see now. You edited your first post and added a link.



Interesting how it converts the C++ API interface to a C compatible one, and then wraps C# classes around the C interface.


I gave the project a try from Linux. I needed to first get some Nuget packages with dotnet restore. The Microsoft build tools don't really know how to build C++ projects from Linux, but I was able to specifically build the C# project with either msbuild OP2UtilityDotNet or dotnet build OP2UtilityDotNet.
Title: Re: OP2 Mission Editor
Post by: TechCor on November 17, 2019, 04:24:23 PM
Yes, the C compatible interface is what needs to compile on Linux. I suppose it needs a CMake file or something. I'm not familiar with it.

Since C# compiles to IL code, the DLL from Windows will work on Linux. The JIT compiler on the user machine should take care of it.

Although, I will need a special DLL anyway to change DllImport to point to the Linux C library. That is something I can prepare easily.

---

Looks like I am able to load and save maps and missions (File Menu). Going to look at rendering tiles to the tile map.
Title: Re: OP2 Mission Editor
Post by: TechCor on November 17, 2019, 11:41:50 PM
EDIT: I fixed it! Turns out the map was upside down and the tile graphic indexes needed to be inverted.

(https://scoriastudios.com/myfiles/op2/MapOffsets2.png)


Update:

Submitted editor source. It's currently just a "Map Viewer" where you can import and scroll around maps, adjust grid overlay color and alpha, and export the map. Not going to bother with a release build yet.
Title: Re: OP2 Mission Editor
Post by: Hooman on November 18, 2019, 01:44:51 PM
I tried checking out the project. There didn't seem to be a project file. I saw some DLL files, but no EXE. Not really sure how to run it.



Meanwhile, the JsonMap (https://github.com/OutpostUniverse/JsonMap) project that was mentioned earlier has been uploaded to GitHub. Probably not directly useful for your editor though.
Title: Re: OP2 Mission Editor
Post by: TechCor on November 24, 2019, 08:13:35 AM
I tried checking out the project. There didn't seem to be a project file. I saw some DLL files, but no EXE. Not really sure how to run it.
The folder itself is the project file. You need Unity to open it.

Update:

Next major task is the paint pane.


Now that I have a better understanding of how maps work, it's clear that the mission API can't fully control the graphic in the tilemap. I thought the entire game was using one big atlas.

I'm thinking the two alternatives now are exporting the map and opm files separately (which is how these are currently read), and/or bundling them into a special mission vol file with a different extension that gets read by the C# Mission SDK. Maybe both.

So options in the File menu could be:

Open (omv / Mission Volume)
Import Map
Import Mission (opm)

Save (omv / Mission Volume)
Export Map
Export Mission (opm)
Export Plugin (Native C DLL hook)

Of course this would require modifying OP2 to look for maps from a different vol extension. Probably not worth it.
Title: Re: OP2 Mission Editor
Post by: leeor_net on November 25, 2019, 03:01:30 AM
Suggestion, it would probably be better to use the GitHub Releases feature instead of providing the release directly in the repository. Just FYI. :D
Title: Re: OP2 Mission Editor
Post by: TechCor on November 25, 2019, 03:24:21 AM
Done.


Quick brief about how to use the current version:

That's it for now!
Title: Re: OP2 Mission Editor
Post by: leeor_net on November 25, 2019, 09:11:03 AM
It's definitely a great working prototype! I gave it a shot last night and was generally impressed.

I dislike the UI as it's not native but that's truly a minor gripe.

Only thing I noticed is that when importing a map, it kinda hangs for a bit. Or at least, it appears to. If I had to guess I'd say it's doing a lot under the hood to convert to an internal format that the editor can work with. Might be good to add a loading text or change the cursor to a wait cursor, something like that. It's a comment about usability and UI's that are 'responsive' to the user. Granted this is early work so I wouldn't go too far into worrying about issues like that before functionality is in place. :D

Anyway, good work! I'm excited to see where this goes.
Title: Re: OP2 Mission Editor
Post by: TechCor on November 25, 2019, 12:56:08 PM
Yes, I would prefer native UI also, but that's the price to pay to use Unity.

I already profiled the import map. Most of the load is coming from color averaging the tiles for the minimap (about 75%). Maybe there is a faster algorithm. I've thought about skipping pixels, but that might affect image accuracy.

Actually, a loading bar is not a bad idea. I can have the percentage be the number of tiles loaded / total tiles. It would would look pretty smooth.
Title: Re: OP2 Mission Editor
Post by: leeor_net on November 25, 2019, 06:10:18 PM
A faster way to do it would be to average the colors of the tilemap itself, build an index table then build the minimap using the index table. E.g., tile index = color index = pixel or however you're generating the map. It's very fast in the prototype code that I built a couple years ago.

Could even pre-cache the index table, e.g., on first run as part of the set up go through all of the tilesets, determine an average color value and store in an index. Can save it out however you think is appropriate and then just load that if the file is present.
Title: Re: OP2 Mission Editor
Post by: Hooman on November 25, 2019, 11:56:13 PM
That's pretty much how the MapImager (https://github.com/OutpostUniverse/OP2MapImager) works. It loads the tilesets, then precomputes scaled tiles for the given scale factor. When it renders the maps, it uses the scaled tileset rather than the original one.
Title: Re: OP2 Mission Editor
Post by: pente on December 09, 2019, 03:52:12 AM
Likewise my python map code precomputes the scaled tiles for the desired scale. I put the code here https://forum.outpost2.net/index.php/topic,6275.0.html (https://forum.outpost2.net/index.php/topic,6275.0.html), it is pretty short and fast thanks to numpy magic.
Title: Re: OP2 Mission Editor
Post by: TechCor on December 13, 2019, 08:41:04 AM
I finally have some time to work on this again.

I now cache a minimap tileset texture along with the regular one when they are first loaded, so that has been optimized. Thanks for the idea, Leeor!

Also removed unnecessary tile refresh which was already happening during SetTiles, and added a progress bar for importing.

Still can't get resourceManager working:
Code: [Select]
extern EXPORT unsigned __int64 __stdcall ResourceManager_GetResourceSize(const char* archiveDirectory, const char* filename, bool accessArchives)
{
ofstream outputFile;
outputFile.open("quicklog.txt");

outputFile << "archiveDirectory = " << archiveDirectory << "\n";
outputFile << "filename = " << filename << "\n";
if (accessArchives)
outputFile << "accessArchives = true\n";
else
outputFile << "accessArchives = false\n";

outputFile.close();

ResourceManager resourceManager(archiveDirectory);
std::unique_ptr<Stream::BidirectionalReader> stream = resourceManager.GetResourceStream(filename, accessArchives);

if (stream == nullptr)
{
ofstream outputFile;
outputFile.open("quicklog2.txt");
outputFile << "hit 0";
return 0;
}

return stream->Length();
}

Prints out:
Code: [Select]
archiveDirectory = E:/Business/Freelance/Projects/Outpost2/Outpost2exe
filename = well0008.bmp
accessArchives = true
...and stream is null.

Tried different archive directories - with/without trailing slash, forward vs back slashes... Can't get it to work.

Will probably have to debug the utility itself to figure this one out.
Title: Re: OP2 Mission Editor
Post by: Hooman on December 13, 2019, 02:25:05 PM
I looked into this. From cursory examination, there may be a bug when the archiveDirectory does not match the current working directory. In that case, when scanning the resource folder for .vol and .clm files, all non-existent files (using the current working directory, not the resource folder) are filtered out of the search results. This causes the archives to not be seen and loaded. That would result in no packed files being found and nullptr being returned for the stream.

Edit: To debug, consider using GetArchiveFilenames to see if any archives are loaded.



Despite my earlier comment, I'm not sure a trailing slash is actually needed. For reference though, I would have used the path:
Code: [Select]
E:/Business/Freelance/Projects/Outpost2/Outpost2exe/

The trailing slash makes the name unambiguously a directory name.
Title: Re: OP2 Mission Editor
Post by: TechCor on December 13, 2019, 05:25:58 PM
You are right; it ignores the passed in directory and uses the working directory.

Confirmed by putting art.vol into the current program directory which is NOT the directory being requested.

The working directory should be used when a relative path is specified. Absolute paths should override the working directory.

Can the OP2Utility project owner please fix this?

I will pull the fix as my copy of OP2Utility has not been changed.

EDIT:
Just want to add that I did check the archive count for the absolute path - it was zero. No archives at the specified directory.
Title: Re: OP2 Mission Editor
Post by: Vagabond on December 13, 2019, 07:55:30 PM
Hooman and I co-curate OP2Utility, although pull requests from the general OPU community would be welcome. I see he opened an issue against the described behaviour. We should be able to fix in fairly short order. Maybe best if Hooman picks the solution. My steering on the ResourceManager and XFile seems to have been poor...

TechCor, why don't you pull OP2Utility as a git submodule into your project so you can pull updates from OP2Utility easier into your project? Also might make it easier to push pull requests if you ever felt inclined.

Sorry for the defective code.

-Brett
Title: Re: OP2 Mission Editor
Post by: TechCor on December 13, 2019, 08:15:58 PM
I've tried looking into submodules before, and couldn't figure it out. Possibly due to a limitation to referring to another user's repositories. I'm not sure.

Sorry for the defective code.
Let him who has not coded bugs cast the first stone. ;)
Title: Re: OP2 Mission Editor
Post by: lordpalandus on December 15, 2019, 02:22:28 AM
I've never coded insects into my code :P.

"Tosses a stone worth of insects at Vagabond."
Title: Re: OP2 Mission Editor
Post by: Hooman on December 16, 2019, 06:51:08 PM
Quote
I've tried looking into submodules before, and couldn't figure it out. Possibly due to a limitation to referring to another user's repositories. I'm not sure.

The mechanics of Git submodules can be a bit strange and unintuitive at times. The worst seems to be that recursive cloning is not the default. There are no restrictions on adding someone else's project as a submodule though. The submodule reference is entirely in the host repository, and doesn't require changes to the submodule's repository. Read-only access is sufficient.
Title: Re: OP2 Mission Editor
Post by: Vagabond on December 16, 2019, 07:27:13 PM
TechCor,

If you are interested in submodules and use TortoiseGit, I can write up a few lines to walk you through it. Hooman could probably write something similar for the Git command line. I understand if you are not interested though. Definitely agree recursive cloning should be default.

Hooman just merged in changes to OP2Utility that should fix the issue you were seeing with the ResourceManager. I think they are changes for the better.

-Brett
Title: Re: OP2 Mission Editor
Post by: TechCor on December 17, 2019, 04:18:23 AM
I see my mistake. I thought it worked like .gitignore, and specifying a .gitmodules file would automatically work. Looks like it is working now.

Only complaint is that my project settings are different, and now I have a "dirty" submodule. Hmm..

Disappointed with how limited GitHub Desktop is. Doesn't appear possible to update submodules, or pretty much do anything with them.

Oh well.

Just tried out the fixed ResourceManager. Works great!

Thanks, Hooman!
Title: Re: OP2 Mission Editor
Post by: Hooman on December 19, 2019, 01:35:54 AM
Git submodules are version locked and tracked by a Git commit hash. If you modify a submodule, either through uncommitted changes, or by updating it to a new commit (such as checking out a new branch, or pulling new changes to master), it will show up as dirty. If you want to update the version of the submodule you are using, you need to make a new commit in the host repository. This is a bit of extra work, but it's also safer, since it ensures the version of the host repository matches up with a compatible version of the submodule dependency.

Be aware that when switching branches, it may not automatically update the submodule version for you. Hence you can also see the submodule appearing to be dirty when you switch between branches that use two different versions of the submodule. From the command line, you would run git submodule update to switch to the last committed version of the submodule.



Glad the changes are working for you.
Title: Re: OP2 Mission Editor
Post by: TechCor on December 22, 2019, 03:56:29 AM
I've added an Export Plugin menu option that pulls the data from the top of Mission Properties and writes it into a plugin DLL using a template.

This all seems to work. I was able to change maps and descriptions and see the effect of flipping "Unit Only Mission" without any compilation.

The only issue I am running into is Outpost 2 is listing the colony mission twice. I'm unsure of what conditions would cause it to create two missions from one DLL. Clicking either of them opens the mission successfully.

In any case, it is looking very likely that compile-free mission building will be a reality fairly soon. :)

EDIT:

So it appears the problem is related to DLL filename length. Anything over 7 characters causes a second mission to be listed.
Title: Re: OP2 Mission Editor
Post by: TechCor on December 24, 2019, 06:10:56 AM
UPDATE:

Terrain painting is in!
(https://scoriastudios.com/myfiles/op2/MapEditPaint.png)

The tile images in the paint window are loaded from the TileMappings that are in the map, grouped by tileset. You can't add new tile mappings (or tilesets) yet, so you would need to import an existing map with these set up.

Some other new features:

I'm going to do Cell Type painting next, followed by resources/units/structures.
Probably going to use a special set of overlay tiles to represent Cell Types that are only visible while in Cell Type mode.


Currently, there are 3 files required for a mission, Plugin.dll, map, and mission. Two, if you reuse a map. Not great but... engine limitations. I'm going to add Export/Import Mission file menu options and change Open/Save to perform all 3.

When you save, you will select the mission file name. Then the map will be exported based on what was set in the mission properties dialog. Finally, the DLL will be exported using the mission file name + the type prefix character based on the mission properties dialog.

When you open, you select the mission to open. Then, it will perform a resources search for the map specified in the mission properties dialog, and load it if it can find it.

This seems like the easiest way to handle mission saving/loading for the map designer. If anyone has any better ideas, I'm open to suggestions.


By the way, does anyone know what TerrainType is for? Looks like it is extra data for TileMapping that wasn't included to save space on duplicate data. It's the only explanation for "tileMappingRange". Setting up the editor to modify that looks like a real pain...
Title: Re: OP2 Mission Editor
Post by: Hooman on December 24, 2019, 06:52:30 PM
Hey, nice progress.

For the TerrainType, best I can offer is to look at the struct definitions, or perhaps find the .txt file about the .map file format. It's stored in the SVN repository along with the OllyDbg info.
Title: Re: OP2 Mission Editor
Post by: TechCor on December 25, 2019, 05:03:03 AM
Moving as quickly as possible while I've got the free time:

(https://scoriastudios.com/myfiles/op2/MapEditCellTypes.png)


Goal is to be able to create a multiplayer-type mission and play against the "experimental" AI by end of year (no triggers).
Title: Re: OP2 Mission Editor
Post by: TechCor on December 27, 2019, 10:07:18 AM
Keeping on:

(https://scoriastudios.com/myfiles/op2/MapEditResources.png)


Unit ID
I removed SpawnRects from the SDK and replaced it with Unit ID. Any object of the same type and the same Unit ID will be selected at random. This gives some good flexibility when it comes to placements. Units with zero/no ID are always placed. Eventually, Unit ID will also be used for triggers.

Future Plans / Mission Variants
While Unit ID is good for random placements, I want to have something similar to missions that have randomized start locations. Eventually, I am going to introduce the concept of "mission variants". By default, you will build on the primary variant. When you are ready, you can duplicate the primary variant, and modify all data that belongs to the new variant. Example variant data would include: Starting people and metals, beacon placements, unit and structure placements, and wreckage placements. A mission variant would be selected at mission start.

--
Up next, going to work on structure placements.
Title: Re: OP2 Mission Editor
Post by: TechCor on December 28, 2019, 06:45:22 PM
Phew! Structures were quite a pain, but it is basically done. Need to tweak the mine text/health bar placement.

Here's what it looks like in the editor:
(https://scoriastudios.com/myfiles/op2/MapEditStructures.png)

...And in case anyone thinks it doesn't actually work, I exported the mission and launched the game:
(https://scoriastudios.com/myfiles/op2/MapEditStructures2.png)

Some notes:

Issue of great importance:

Structures currently do not take on the color of the player. The images are PNGs with the Eden color baked in (these were converted from "art viewer"). I cannot think of an easy way / algorithm to convert the blue player color to another color. If anyone has an idea of what a shader algorithm would look like, let me know!

Otherwise, the only other option appears to be cutting out the player colors by hand for each frame (there are 1000), and making them a gray-scale overlay image that get tinted. The likelihood of me wanting to cut all those frames is extremely low.
Title: Re: OP2 Mission Editor
Post by: Vagabond on December 29, 2019, 01:15:29 PM
The old map editor spits out a source code file containing structure locations. That allowed the dll to properly assign colors once a game was initialized. If you are supporting multiplayer maps, I don't see a way around this since you won't know the color when making the map of each player.

The color is achieved by changing out an indexed bitmap pallet. There are 2 console modules cm1 and cm2 that demonstrate this if you want to check them out. Although I suspect you are looking for a more out of the box solution.

Looks like you have made some great progress.

Brett
Title: Re: OP2 Mission Editor
Post by: TechCor on December 29, 2019, 02:01:09 PM
I actually have no idea how the old map editor works. I looked at it about a year ago, but it was throwing exceptions (if that's the one you are talking about).

What I'd really like, is for OP2Utility to be able to read the .prt and art files and break the data into a digestible form. So essentially, I would read through a list of Sprite Groups, assign them to the appropriate map_ids, extract and convert the bitmaps similar to how I did the tiles, and reconstruct the sprites in the editor. I could even have everything animated.

Of course, that would be a lot of work. Too much to ask for, and too much effort for me to figure out the data formats myself compared to converting the bitmap frames to PNGs. Gotta get stuff done! ;)

So, the palette information is lost.

That's OK. I might pay a freelancer to cut up the player colors from the frames, or maybe I'll have time one day to extend OP2Utility. We'll be waiting a long time for the latter though. So many other things to work on.

Absolute worst case, I stick a colored circle on the structures to represent player color.
Title: Re: OP2 Mission Editor
Post by: Vagabond on December 29, 2019, 06:21:54 PM
I don't think the palette information is lost, I'm just not sure if there is an easy way for you to swap palettes real time in the map editor as Outpost 2 would handle it.

Yeah, I feel bad for not finishing the .prt and .bmp parsing for OP2Utility. There is a decent amount of work remaining to complete it, although I'll keep in mind you are looking for it. I think there are other priorities for me right now concerning OP2.

What I was trying to get at is that the color of a building is not set until a level is loaded since a player could choose a different color for multiplayer maps. How will your map editor handle this? I don't actually know what happens if you place a blue CC on a map and then start a mission as magenta... Maybe it would all work out?

I could send you a sample of the previous map editor's output. It is basically a .cpp file containing the code to create all the buildings for each player using TethysGame::CreateUnit. You could then include that .cpp file in your source code and have fully constructed starting bases without baking the building tiles into the map the map editor created. This really isn't a great solution, but I'm assuming it was the best that could be done for a reason.
Title: Re: OP2 Mission Editor
Post by: TechCor on December 29, 2019, 07:21:16 PM
Oh, I see. I'm cutting the weapons now, and just thought about how the player color is still there, so if I can just find out what RGB values are used for the player color in the palette, I can pull the pixels and create gray-scale textures at startup, or better, make a shader that swaps on the fly. Just have to get the palette information...


Buildings aren't baked into the map tiles. The images just represent the building's location in the editor. The editor dumps the building locations and other info into a JSON file to be processed by the DotNetMissionSDK. TethysGame::CreateUnit ultimately gets called in the end.

The colors that will display in the editor will be whatever is set in Player Properties. When the game launches, the colors will only be set for single player missions with SetColorNumber().
Title: Re: OP2 Mission Editor
Post by: Hooman on December 29, 2019, 08:24:38 PM
Looks like pretty good progress.



For the player colors, the game does some palette remapping. I'm pretty sure there's something posted to the forums somewhere, and the art_reader utility could handle it. As I remember it, one of the palettes contains all the player colors. If I remember correctly, there are 32 palette entries for each player color, covering all shades of the color. That leaves room in a 256 color palette for 8 player colors, at 32 shades each. For the unit sprites, I believe the bottom 32 colors are remapped according to the player color palette. Just multiply the player number by 32 to get the starting block of the player's color. That block of player colors is used in place of the lower 32 colors of the image's referenced palette. I believe there is some kind of attribute flag bit for sprites, so the game knows what images to do this for.
Title: Re: OP2 Mission Editor
Post by: Vagabond on December 29, 2019, 09:42:22 PM
For an example color palette, see: https://forum.outpost2.net/index.php/topic,3907.msg62442.html#msg62442

For the code to modify the pallet within Outpost 2 see: https://forum.outpost2.net/index.php/topic,4332.msg65267.html#msg65267

The original palette should be contained in art.prt if not somewhere on the forum. OP2Utility may be robust enough to extract it with a little massaging. I could try to help extracting it if you would like to have it available and it isn't somewhere else on the forum already.

-Brett
Title: Re: OP2 Mission Editor
Post by: TechCor on December 30, 2019, 08:30:25 AM
Thanks. I think I figured it out.

Player color palette is stored in Color.bmp. Popping it open in Gimp, looks like 24 colors per player, Blue, Red, Green, Yellow, Cyan, Magenta, then the rest of the palette is solid black.

I don't have any way to read the bitmap palette, so I'll recreate this in a PNG, and write a shader that takes an offset and count.

Looks like the images I'm using default to the first color, so I'll use that to determine which pixels need to change. Hopefully there aren't any duplicate RGB values in the source images.
Title: Re: OP2 Mission Editor
Post by: Hooman on December 31, 2019, 02:50:26 PM
Glad you figured it out. Thanks for the correct on the color count.

Do you plan to do the color remapping from an 8-bit indexed bitmap, or were you planning on converting images to true color and then somehow recognizing and remapping colors that way? If so, it's possible there could be some color reuse. I'm not aware of any though. Of course, this would be a great opportunity for someone to create a new color mod just to mess with that idea.  ;)
Title: Re: OP2 Mission Editor
Post by: TechCor on December 31, 2019, 08:47:18 PM
All the images are in true color, so yes, it's going to be a bit hacky, and it doesn't work with mods. I see this as a temporary measure until OP2Utility can provide adequate sprite data. I figure it'll be in use for the next year or two.
Title: Re: OP2 Mission Editor
Post by: TechCor on December 31, 2019, 09:40:04 PM
Painstakingly set up all the vehicle offsets. Here it is:
(https://scoriastudios.com/myfiles/op2/MapEditUnits.png)

My little "game jam" is coming to an end, so I am going to post a build to all the work that was just completed:

Mission Editor v0.2.0
https://github.com/TechCor8/OP2MissionEditor/releases/tag/v0.2.0 (https://github.com/TechCor8/OP2MissionEditor/releases/tag/v0.2.0)

This is still very much pre-release. However, you can definitely set up a basic mission and play against the DotNet AI! No compilation required!

Unfortunately, no walls/tubes or player colors, but that will get in there eventually. Over the next couple months, I will focus on usability features such as a placement overlay, units on the minimap, player colors, moving and editing existing units, etc.


Editor Tutorial:

BACK UP YOUR OUTPOST 2 DIRECTORY. The editor does not confirm when overwriting files, and things can go very badly if you don't know what it is doing!
Known Issues:

That is it for now. There is still so much more planned! Let's hope 2020 is another productive year for Outpost 2 development!
Title: Re: OP2 Mission Editor
Post by: TechCor on January 05, 2020, 11:46:22 PM
Mission Editor v0.3.0:
https://github.com/TechCor8/OP2MissionEditor/releases/tag/0.3.0 (https://github.com/TechCor8/OP2MissionEditor/releases/tag/0.3.0)

This version focuses on usability improvements for existing functionality.


Upcoming:

Note: Guard post crashing has been fixed in the DotNetMissionSDK, which is included in this release.

If anyone knows the lighting algorithm used by the game, please let me know about it. I'd like to emulate the light settings in the editor. Thanks!
Title: Re: OP2 Mission Editor
Post by: Vagabond on January 06, 2020, 09:44:10 PM
TechCor,

The editor is looking great. I downloaded it and give it a try. A couple of thoughts below. I'm overall very impressed, so don't take these as negative. It is a pretty massive project.

A big feature request is to store the cell index associated with a terrain tile and automatically update the cell index when the tile is placed. I spent many hours in the old mapper updating cell indexes to match my terrain types, when I usually just wanted to change the cell index to the default value of the terrain image. It would be nice to maybe disable this feature temporarily if desired, but default to updating the cell index. I know mapping all the cell indexes to tiles could be a pretty big time suck.

1. The initial dialog to change screen resolution and grid color doesn't seem to have an accept or ok button. I just used the top right X, but might be nice to add an OK button as I was a bit confused if it would cancel my settings or not.

2. I tested it on a laptop. The terrain tiles on the right side of the screen are pretty small. I had a difficult time distinguishing the tiles. It would be nice if they could be maybe doubled in size or more.

3. I tried creating a new mission. It just flashed a small dialog box too small for me to see and didn't seem to do anything else. When I tried opening an existing map everything seemed to work.

I appreciate that you allow saving maps in the original format. This would allow people who want to use C++ for mission development to still use your editor for map editing.

----

Concerning the lighting. Do you mean the shadows on buildings and vehicles or the day night cycle or building/vehicle lights in the dark?

The unit shadows are simply 1 bit bitmaps that are added to each image. They are contained in the .prt/.bmp file like other sprites.

The day night cycle and edge of light is produced by applying a mask over the tiles. The same principle is used for the blight but a different color is used. Hooman wrote a sample program to show how it works and you can find some details here: https://wiki.outpost2.net/doku.php?id=outpost_2:helper_programs:virus_mask. The program is written in Visual Basic and the source is available, so you could inspect it. I have a hard time reading Visual Basic code not being fluent in the language.

Quote from Hooman in how light/dark tiles are completed internally:
Quote
When determining which tile to display, it examines 4 tiles in a 22 setup, using 1 bit from each tile to get a 4 bit index. (There are 16 tiles in VirMask.raw). It's probably easiest to think of the actual virus display as being off by half a tile.

I believe VirMask.raw is contained in Art.vol.

----
EDIT: It appears the SVN repository is down again, so you might not be able to pull the source code. Someone might have a copy of it though if you want to inspect.
Title: Re: OP2 Mission Editor
Post by: TechCor on January 07, 2020, 12:52:43 PM
Thanks for the feedback.

I can have some code pull the most commonly used cell types for a tileset + graphic index from a bunch standard OP2 maps and  write it to a config file. Those can then be painted at the same time as the terrain graphics.

I haven't been focusing too much on the map capabilities since map editors already exist, so mission work is taking priority. Eventually, I want to add the ability to edit tilesets, mappings, terrain types, and create and paint tile groups.

- I will increase the size of terrain buttons to match structures/vehicles.

- When you start up, you are already looking at a new mission (no map loaded). If you import a map and then create a new mission, you will notice that you are taken back to this screen. I would have liked to select a blank map of some size, but starting from scratch looks complicated (no tilesets, mappings, or terrain types), and OP2Utility does not seem to support it anyway.

---
I was actually looking for how the big window/column of light is calculated. I assume it is some multiplier like "1 is daylight" and "0.25 is night" with some X sized column width, and Y amount of falloff. Also important is how the "initial light level" is applied, and perhaps the movement rate when daylight moves.

Knowing the other stuff will be helpful later, since I could have vehicle lights and paint blight.
Title: Re: OP2 Mission Editor
Post by: Hooman on January 13, 2020, 07:58:18 AM
It's been a while since I looked at the day/night cycle code. I don't think it was ever understood in great detail, though there were a number of calculations that were noted down. Well, the integer math was noted down. This is one of the few places in the code where floating point was used.

In OllyDbg, there was an object marked as DayNight. Internally, there is a daylightPosition field, which ranges from 0..65535. There is also another associated field actualDaylightPosition, which is set to daylightPosition * Map.tileWidth / 65536. Despite the name, it's possible that point actually represents the darkest point on the map.

During the update cycle, daylightPosition is incremented by 4. I'm not certain, but I suspect this update cycle is called every 4 ticks, so that may be why. The actualDaylightPosition is then updated according to the formula. The game engine doesn't have any other global references to the daylightPosition field, though does have a number of references to the actualDaylightPosition field.

When drawing unit graphics, the internal graphics API has a lightLevel parameter. It is calculated as Unit.tileX - actualDaylightPosition. There is some code that artificially bumps up the lightLevel by 512 when bDaylightEverywhere is not set. I had to check that a few times to make sure I was reading it right. From the looks of it, it might actually be a darkness level rather than a light level. In other places, if bDaylightEverywhere is not set, it bumps up the lightLevel by Map.widthInTiles.

There is also a Map.lightLevelBrightnessAdjustment array, which is an array of bytes (char). I believe that array somehow maps on to the bands of day/night across the map, though I don't think that area is well understood. In particular, I've never been too certain on how it determines the width of day/night regions.
Title: Re: OP2 Mission Editor
Post by: TechCor on January 14, 2020, 12:50:54 AM
Very cool. I want to expand HFL to include some of these items so I can view the contents, and maybe add the ability to control the day/night cycle speed. :)

I assume "Map.lightLevelBrightnessAdjustment" is referring to "54F854   0x5C   char[] lightLevel". What size is this array? numTiles?

Trying to understand this:
actualDaylightPosition is the current tileX daylight is on which wraps at map.tileWidth i.e. if the map is 256 wide, actualDaylightPosition is 0-256. Kind of a clever way to avoid a conditional wrap.

It looks like the "lightLevel" is the distance from the "actualDaylightPosition". To avoid a negative value, it adds 512 to it (max map width).
tileX - actualDaylightPosition + 512 = lightLevel:
0 - 512 + 512 = 0 (dist = -512, lightLevel = 0)
511 - 512 + 512 = 511 (dist = -1, lightLevel = 511)
511 - 256 + 512 = 767 (dist = 255, lightLevel = 767)
511 - 0 + 512 = 1023 (dist = 511, lightLevel = 1023)

Trying to envision what this would look like, but it seems like something is off. Maybe actualDaylightPosition/lightLevel is not related to the actual daylight, but instead lightLevel is an index into the "lightLevelBrightnessAdjustment" array (size 1024). Then the value returned from that array is used as a multiplier. This would give you "bands of light".

Total speculation, of course. :D
Title: Re: OP2 Mission Editor
Post by: TechCor on January 20, 2020, 03:26:54 AM
Doing a somewhat light (pre)release because of a breaking change, as I will not be available for a couple weeks. I don't anticipate any other breaking changes in the future, but can't guarantee that there won't be.

This introduces "Mission Variants" which allows for fairly good randomization of mission startup parameters without the need for code (or triggers in the future).

https://github.com/TechCor8/OP2MissionEditor/releases/tag/0.4.1 (https://github.com/TechCor8/OP2MissionEditor/releases/tag/0.4.1)

EDIT:
v0.4.1 - Added difficulty settings for "Gaia" units. Changed difficulty to use additive-override settings the same way variants were working. The benefit is decreased mission file size, more manageable work flow, and the ability to manipulate beacons and wreckage based on difficulty.


Breaking Change
Mission format (.opm) has changed to support "Mission Variants" and "Player Difficulty". Backwards compatibility is not available for pre-release builds. Mission files are human readable, so you can manually upgrade if you wish by adding the appropriate attributes.

Overview
Mission Variants and Player Difficulty are controlled through the new Mission Variants window found in the View menu. Mission Variants allow randomization at the start of a mission to help give it a bit of a unique flavor and prevent things from being too predictable. Player Difficulty settings affect starting resources and settings for single player and multiplayer games.

Mission Variants
Variants affect game settings such as daylight and music, as well as all units such as beacons, markers, wreckage, and all player settings and units. When the game starts, the master variant is always applied, and then a random variant is chosen to be applied as an additive override - the variant's units and resources are added, and non-countable settings like daylight and music override the master variant's settings.

Player Difficulty
Player difficulties affect a specific player's morale, tech, and units (resources) based on their chosen difficulty level. The default player resources will be applied to all difficulties, and then the chosen difficulty's resources will be added on top of those resources. For example, if "all difficulties" is set to 500 food, and "easy" is set to 100, the player will receive 600 food for selecting easy difficulty. Settings such as morale are overridden by the difficulty's settings. If a mission does not contain a difficulty, only the default resources are given. In our example above, it would be 500 food.

In single player, all players use the local player's difficulty settings. This means that AI player resources can be adjusted based on the selected difficulty.

Beacons, markers, and wreckage (gaia units) are only affected by difficulty in single player. These follow the same rules as above based on the local player's difficulty selection. This is useful for controlling beacon placements and whether wreckage is visible in lower difficulties. In multiplayer, only default resources ("all difficulties") will be applied.

Workflow
By default, you are working on the master variant with "all difficulties" selected. The recommended workflow is to set up all non-variant resources and units for "all difficulties". Then, you create easy mode and add resources and units. Finally, when creating normal and hard, you can duplicate easy mode and remove resources and units.

After the master variant is finished, you can create a new variant which contains duplicate settings and no resource or unit data. Because variants are applied additively to the master variant, you will only need to make changes specific to this variant, such as additional resources and different beacon or player start locations. When adding a variant while another variant is selected, you will duplicate that variant's data.

Player counts and difficulty levels must remain uniform across all variants (enforced), so be careful when deleting those values as you will lose that player or difficulty for all variants.

Changes:
- Added Mission Variants and Player Difficulty settings.