1.0.1 • Published 8 months ago

bwmapimage v1.0.1

Weekly downloads
-
License
MIT
Repository
-
Last release
8 months ago

MIT license npm version

BwMapImage

Library for generating map images for StarCraft: Brood War and Remastered.

Both map files (.scm and .scx) as well as replay files (.rep) are supported as input.

This is a wrapper library around the bw-chk, jssuh and scm-extractor libraries made by the Shield Battery project. All the heavy lifting is done by their code—this library mostly just simplifies the process and passes the result through an image encoder.

Usage

This library is available via npm.

npm i --save bwmapimage

Basic usage involves passing a filename and getting an image buffer in return:

import fs from 'fs/promises'
import {BwMapImage} from 'bwmapimage'

const bwMapImage = new BwMapImage('(4)Vermeer SE_2.1.scm', {})
const [buffer, metadata] = await bwMapImage.renderMapImage()
await fs.writeFile(`out${metadata.extension}`, buffer, null)

By default, the library will generate a full size .png file (which can take a bit of time and be quite large).

Reference

Function:

new BwMapImage(file, options)

Parameters:

  • file string|buffer\ Either a path to a .scm, .scx or .rep file; or a buffer of one of such files.
  • options object|null\ See below.

Returns:

A BwMapImage object for the given file and options object.

For the source file, you can pass either a string or a buffer. If a string is passed, the file will be read from disk, with the file type assumed from the extension; a buffer will be processed in the same way.


Function:

await bwMapImage.renderMapImage()

Returns:

  • buffer string\ Image buffer that can be directly saved to a file.
  • metadata.type string\ Either "map" or "replay".
  • metadata.extension string\ A recommended file extension for the given format, e.g. ".jpg"
  • metadata.format string\ Image format used.
  • metadata.channels number\ Number of channels in the output image.
  • metadata.size number\ Size of the buffer in bytes.
  • metadata.width number\ Final width of the image buffer after resizing.
  • metadata.height number\ Final height of the image buffer after resizing.
  • metadata.fullWidth number\ Full width of the bitmap prior to resizing.
  • metadata.fullHeight number\ Full height of the bitmap prior to resizing.
  • metadata.mapTitle string\ Raw title for the map. Contains escape sequences.
  • metadata.mapDescription string\ Raw description for the map. Contains escape sequences.
  • metadata.mapHash string\ XXH64 hash of the map data, for caching purposes.
  • metadata.mapTileWidth number\ Map width in tiles.
  • metadata.mapTileHeight number\ Map height in tiles.
  • metadata.mapTilesetId number\ Tileset ID for the map—see sctoolsdata for more information.
  • metadata.mapEncoding string\ Character encoding for the map; typically either "cp949", "cp1252" or "utf8".
  • metadata.resolvedOptions object\ The user's passed options with default options merged in.

Generates an image from a map or replay file.


Function:

await bwMapImage.getMapMetadata()

Returns:

  • metadata.mapTitle string\ Raw title for the map. Contains escape sequences.
  • metadata.mapDescription string\ Raw description for the map. Contains escape sequences.
  • metadata.mapHash string\ XXH64 hash of the map data, for caching purposes.
  • metadata.mapTileWidth number\ Map width in tiles.
  • metadata.mapTileHeight number\ Map height in tiles.
  • metadata.mapTilesetId number\ Tileset ID for the map—see sctoolsdata for more information.
  • metadata.mapEncoding string\ Character encoding for the map; typically either "cp949", "cp1252" or "utf8".

This returns metadata about the map data itself, before the image is generated. This allows for you to, for example, check the mapHash against a cache. Note that the hash is specific to the map data, not to the generated image.

Options

The following options can be passed:

SettingTypeDefaultNotes
bwGraphicsPathstring|nullnullIf null, this gets set to ~/.config/bwmapimage, where ~ is the user's home directory.
forceTypestring|nullnullEither "map" or "replay", but normally autodetected.
tileSizenumber32Either 32, 16 or 8. Base tile size; 32 is full size, anything smaller results in smaller images for much less processing time and memory.
encoderTypestring"png"E.g. "png", "jpeg", "avif", etc—anything supported by sharp.
encoderOptionsobject{}Options passed on to sharp for the given output type.
targetWidthnumber|nullnullWidth the image will be resized to. See target size note below.
targetHeightnumber|nullnullHeight the image will be resized to.
targetFitstring|null"inside"Resizing fit; typically you want "inside". See the sharp api for other options.
preHookfunction|nullnullCallback for manually utilizing the sharp object with the full size map image buffer (prior to resizing).

Note that, by default, this library will create a lossless .png file at full size. This is extremely time consuming (on a fast machine it can take 3-5 seconds) and results in huge files (10–15 MB, 4096×4096 for a 128×128 tile map). It will also take a lot of memory to generate the initial uncompressed bitmap.

To downscale the resulting image, you only need to set one of targetWidth or targetHeight; if you set one, the final image will be resized within a square by that size. So if you set one of them to 512, a square map like Fighting Spirit will end up being 512×512, and a slightly thinner map like Invader will be 512×448.

The preHook value can be used to manually do something with the sharp object before the image is finalized and returned. For example, here's a function that boosts the brightness of the generated images:

/** Converts Photoshop style levels to linear multiplier/offset values. */
function levelsToLinear(min, max) {
  const a = 255 / (max - min)
  const b = -min * a
  return [a, b]
}

await makeBwMapImage('map.scm', {
  // see: https://sharp.pixelplumbing.com/api-operation#linear
  preHook: image => image.linear(...levelsToLinear(0, 150))
})

The callback runs prior to resizing and compression.

Graphics

To be able to generate map images, you'll need to extract the required graphics from StarCraft.

A copy of the required graphics can be found here (18.5M), provided for convenience reasons.

You can also extract them from the game files directly using a program such as CascView.

The following files are needed:

  • all files listed in units.js and sprites.js files from bw-chk;
  • for all tilesets ['badlands', 'platform', 'install', 'ashworld', 'jungle', 'desert', 'ice', 'twilight'], all files of extension ['.cv5', '.vx4', '.vr4', '.wpe', '.vx4ex'].

All filenames should be lowercase, as that's how bw-chk expects them to be (although on case insensitive filesystems this doesn't matter).

By default, the library will look for the graphics in the ~/.config/bwmapimage directory.

External links

License

MIT license.

1.0.1

8 months ago

1.0.0

8 months ago