Full source code (LGPL) and usage instruction (readme.txt) inside.
I will start making skies for OA at the same time as I create a dedicated website for this program.
This week I overcame a significant hurdle: GZDoom sky export.
This format is grossly inefficient, stretched non-linearly in a tricky pattern: while the texture has to be 1024 x 512 to avoid auto-repeating, the horizon line is only at 207 pixels from its top.
Trial and error, guys, trial and error. Sniff.
Be thankful, I made it in Blender. In Blender, man!  
 because Blender interface was made by Chthulhu in Hell.
CheSkymp is a skybox composer optimized for fast reassembly with one click/launch. Meaning it operates in the same way as compilers do: There are sources, in this case images and the sky definition .INI file that are processed into output skyboxes.
The main advantage of this is the ability to keep several output skyboxes synchronized without doing that manually (e.g. you have one hard-alpha sky map and one blurred shadow sphere map).
A secondary advantage is that your sources are not changed during the composition process so there are no accumulating errors.
The main disadvantage is non-visual, you have to keep your skybox layout in your mind. 
To work, CheSkymp needs a sky definition (using .INI file format) that describes the skybox(es) to make
NOTE#1: the [section]:ident notation I use in this readme refers to a string
ident=<value>
inside a block delineated by an opening string
[section]
That is all there is about the .INI file "syntax".
NOTE#2: all color calculations are performed in floating point and only culled to 0.0..1.0 when written to the output image. So layer blending modes like myltiply *can* surprise you, you *can* specify out-of-range colors like 2.0,2.2,11 and you *can* get and use *negative* brightness values.
NOTE#3: the decimal separator in floating-point values is dot, regardless of system locale and stuff.
NOTE#4: absolutely all operations on the input bitmaps use Lanczos filtering.
NOTE#5: the difinition is NOT case-sensitive. Unless you work with file names in Linux, there is absolutely no distinction between mylayer and MyLaYeR
[project]:input_path
   Input path where CheSkymp searches for source images. If not specified, the path to the .INI file will be used. Can be declared as relative.   
[project]:output_path
   Output path where CheSkymp places the generated skybox bitmaps. If not specified, the .INI file path will be used.  Can be declared as relative.   
[project]:debug   
   If set to 1, will screen any exceptions during bitmap generation, filling these pixels with magenta.   
[project]:output_image_format
   Default is tga. Please note this is file extension without the dot that is passed directly to Vampyre Imaging Library. No checks are performed. It is up to you to use right kinds of formats and not try saving image with transparency into a JPEG.   
[project]:supersampling
   NOT IMPLEMENTED YET 
      [project]:output
   A list of comma-separated output layer identifiers. Please note that output image name is (usually) output layer identifier with extension added.
   Note that outputs can share input layers!   
[<output layer>]:type
   The type of skybox being generated. Valid values are:
   sphere_map
      Bog standard sphere map. Forward vector (zero direction) is the exact middle of the bitmap.
   gzdoom_sky
      A specific kind of sphere map, distorted non-linearly to counteract non-linear stretching in GZDoom). Zenith and nadir regions are not present (so there is information loss when exporting tinto this format). The game engine fills zenith and nadir with solid color derived from the image edges averaged.
      The bitmap size is forced 1024x512 
   q3_cube_map
      A cube map in the format used by Quake 3 and games built on its engine, like Open Arena. Six images will be generated, with suffixes _ft, _lf, _rt, _bk, _up and _dn.
[<output layer>]:layers
   A comma-separated list of layer identifiers
   Nothing is stopping you from including the same layer several times.      
[<output layer>]:input_path
   Optional. Overrides the project-wide setting.
[<output layer>]:output_path
   Optional. Overrides the project-wide setting.
[<output layer>]:output_image_format
   Optional. Overrides the project-wide setting.
[<output layer>]:supersampling
   Optional. Overr-- NOT IMPLEMENTED YET, DAMMIT 
   [<output layer>]:alpha
   Boolean value (set to 1 to activate). Determines if the image would have alpha channel. If not, black background would be in stead of transparent areas. Of course, output image format has to support it.   
[<output layer>]:hdr
   !UNTESTED! 
   Boolean value (set to 1 to activate). Output image would be unculled floating-point RGBA32F. Of course output image format has to support this.   
[<output layer>]:flip
   Boolean value (set to 1 to activate). Causes the output image to be flipped horizontally.
   NOT supported by cube maps.
[<output sphere map layer>]:height   
[<output sphere map layer>]:sphere_width
   You can specify only one of them, then another one would be derived from assumption that width is double the height.
   Width is clipped to 8192, height to 4096   
[<output sphere map layer>]:non_closed_horizontally   
   Boolean value (set to 1 to activate). Depending on the method you use to render your sphere map, it would be proper (with interpolation between the right and left side texels where the edges meet). By default it is assumed that you use a crude hack of a spherical model with its edges welded shut, so the right and the left map sides are exactly the same position and their pixels must be equal. basically, you sacrifice one pixel of your equator length for the sake of simplicity.   
[<output cube map layer>]:height
   Width is always equal to height.   
[<input layer>]:type
   The type of layer. Note that most layers support variety of blending modes a la Photoshop!
   group
      Layer group. Has its own blending mode as well as the list of child layers. see below.
   sphere_map
      Sphere map.
   sprite
      A single image projected onto the skybox.
   color
      Solid color. See below.
   gradient
      A conical gradient. See below.      
[<input layer>]:bitmap
   Specifies image file for sphere map and sprite type layers, ignored otherwise.
[<input layer>]:flip
   Boolean value (set to 1 to activate). Causes the input image to be flipped horizontally.   
[<input layer>]:opacity
   Floating-point value that defines the layer opacity. Default is 1.0   
[<input layer>]:mode
   Blending mode. Default is Normal. Valid values are:
   Normal
   Multiply 
   Divide
    Screen 
   Overlay 
   Dodge 
   Burn 
   Hard_Light
   Soft_Light 
   Grain_Extract 
   Grain_Merge
    Difference 
   Addition 
   Substract 
   Darken_Only 
   Lighten_Only,
    Hue
   Saturation
   Color
   Value
   For what they do, refer to any Photoshop / TheGIMP tutorial.
   Note that hue, saturation and color work differently from classic Photoshop behavior. When encountering source pixels with absolutely no color, white "color" will be produced instead of skipping that pixel and making the layer transparent.
[<input layer>]:yaw   
[<input layer>]:pitch   
[<input layer>]:roll
   Floating point numbers specifying layer rotations in degrees.
   Initially, any input layer is positioned around the forward vector (dead center of the sphere map bitmap).
   First, yaw (rotation around the vertical axis) is applied. Positive angle is right.
   Second, pitch (rotation around horizontal axis perpendiculat the direction vector) is applied. Positive angle is up (90=zenith, -90=nadir)
   Finally, roll (rotation around the direction vector) is applied. Positive angle is clockwise.
   Have no effect on solid color layers.   
[<input layer>]:y_shift   
   Alternate way to specify pitch for sphere map and sprite type layers (ignored otherwise). 
   The angle is in input bitmap pixels.
   Positive shift is UP.
[<input layer>]:x_shift   
   Alternate way to specify yaw for sphere map and sprite type layers (ignored otherwise). 
   The angle is in input bitmap pixels.
   Positive shift is right.      
NOTE: the sprite's direction vector goes through the center of its bitmap, so sprite with zero yaw and pitch will land in the center of the output sphere map.   
[<sprite layer>]:angle
   Floating-point value in degrees dictating the size of the sprite on the sky. The angle is taken across the mid-point, across width or height (whichever is greater). Sprite edges cannot touch together, so maximum attainable angle for a square image is about 254 degrees (may be significantly larger for thin strips, but always less than 360).   
[<sprite layer>]:size   
   Alternative way to set angle. 
   This value is in pixels of the output bitmap. The resulting angle is calculated relative to the sphere map width (a good enough approximation), or double the cube map height (which is rough and imprecise).   
[<sprite layer>]:force_aspect
   Floating-point value. Forces aspect (height to width ratio) regardless of the bitmap's actual dimensions.   
[<sprite layer>]:aspect_correction   
   Floating-point value. Aspect (height to width ratio) is multiplied by this.
   Ignored if force_aspect is set.   
[<solid color layer>]:color
   Three or four floating-point values separated by commas, for red, green, blue and optional alpha.
   If alpha is omitted, it is set to 1.0   
[<gradient layer>]:start_color
   Three or four floating-point values separated by commas, for red, green, blue and optional alpha.
   If alpha is omitted, it is set to 1.0   
[<gradient layer>]:end_color
   OPTIONAL. If omitted, the end color is the same as the start color but with alpha set to 0.
   Three or four floating-point values separated by commas, for red, green, blue and optional alpha.
   If alpha is omitted, it is set to 1.0   
[<gradient layer>]:start_angle
[<gradient layer>]:end_angle
   Floating-point values culled to 0.0..180.0
   Please note that *all* gradients are conical, due to spherical nature of the sky space.
   If any omitted, 0 is assumed but you *have* to declare either.
   Angles less than start angle are filled with start color, and angles greater than the end angle are filled with end color.
   Examples:
      A fuzzy spot: end_angle=30, no start_angle
      A clear spot in a sphere of solid color: start_angle=30, no end_angle
      A basic sky with a blurred horizon: start_angle=80 end_angle=100, pitch=90, start color blue and end color brown.   
[<gradient layer>]:power
   Floating-point value that dictates how non-linear the gradient would be. 
   Culled to 0.0001..10000.0
   Default is 1.0
   Basically, a power of transitional value between 0.0 (start) and 1.0 (end) would be taken. Remember how power functions behave in this range: 0.5 is square root, so mid-point would be shifted towards the start. 2 is square, so mid-point would be shifted towards the end.   
[<group layer>]:layers
   A comma-separated list of layer identifiers
   Please note that groups can share layers without limit! Make sure you don't create circular references or CheSkymp would hang.