Importing levels from Graal

Started by Zaidyer, February 04, 2017, 03:10:10 PM

Previous topic - Next topic
February 04, 2017, 03:10:10 PM Last Edit: February 04, 2017, 03:45:09 PM by Zaidyer
Graal has been mentioned a few times here. It's a game from 1999 that originally began as a Zelda clone and editor, very similar to Solarus in most respects. It was re-named to Graal in an attempt to break away from Nintendo's IP and eventually become a commercial game. Unlike Solarus, it has built-in netcode for online play which eventually became the focus of the engine.

Graal is fondly remembered as a (formerly) free development platform for online games with Zelda gameplay, and is mostly known today as a popular iPhone game, but it is currently under the control of a company which is infamous among long-time players and its former employees for predatory terms of service and a consistently quasi-legal approach to business. (In fact, even the game's lead programmer eventually left, citing the head of the company as very bad to be in business with.)
It's sufficient to say Graal is no longer an ideal platform.

Now that the classic Graal engine is on its way out, Solarus neatly outdoes it.
Documentation from Graal's former free years isn't easy to come by, but I have some old backups, including a collection of levels that my friends and I built a long time ago which I'm hoping to get converted to Solarus. There's enough material for a large quest here.

The Graal level format is text-based and details a 64x64 tile grid, referencing a single tileset with 4096 patterns. Here's the official documentation:
Format:
  It begins with the signature GLEVNW01.
  It can contain following data types:

  - board lines:

    BOARD x y width layerindex <tilesdata>

    This is one line of the background layer. 'tilesdata' has a length if w*2
    characters; each tile is a 12bit-index into the tile list (pics1.png) and is
    encoded in two base64 characters (upper 6 bit first)
    base64: String = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    so AA is tile 0, AB is tile 1, AC is tile 2, // is tile 4095 (=0xFFF)

  - level links:

    LINK <destination-level> x y width height newx newy

    The link attributes are the same like in the link options window in Graal.
    destination-level, newx and newy must not contain spaces.

  - signs:

    SIGN x y
    text
    ...
    SIGNEND

    Signs may be empty, but SIGNEND must always be there.

  - npcs:

    NPC imagefilename x y
    script
    ...
    NPCEND

    If the npc doesn't have a filename (invisible npc), then write '-' for imagefilename.
    x and y may be floating point values. The npc script may be empty, but NPCEND
    must always be there

  - baddies:

    BADDY x y type
    attackverse
    hurtverse
    winverse
    BADDYEND

    'type' is the baddy name (graysoldier ... dragon ) or index (0...9). You don't need
    to write all 3 verses, it's also possible to only write attackverse+hurtverse or only
    attackverse, but BADDYEND must always be there.

  - chests:

    CHEST x y item signindex

    item is the item name (greenrupee ... spinattack) or item index (0...24)



Simple, right? This could be translated to Solarus's own text-based map format, probably by writing a converter. The trick, I think, is making sure the Base64 tile grid can be re-interpreted to apply to a Solarus tileset. And while almost everything else has a direct analogue in Solarus, NPCs "script" field would have its own challenges which I think are best ignored, since it's a proprietary language that wouldn't translate directly to Lua without a considerable amount of effort.

Here is a sample of an actual level:
GLEVNW01
BOARD 0 0 64 0 FDFEFCHNHOHPIyIzJtf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/HkGOGOGOGOGOG7f/f/f/f/f/f/f/f/f/f/f/ABf/f/f/f/f/f/f/f/f/f/DiDjDkCqCqCqCqCqCqCq
BOARD 0 1 64 0 FCFCFCHdHeHfJCJDJ9f/f/f/f/ABf/f/f/f/f/f/f/f/f/f/f/HkGOGOGOGOGOG7f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/DSDTDUCqCqCqCqCqCqCq
BOARD 0 2 64 0 FCFCFCHNHOHPIyIzJtf/f/f/f/f/f/f/f/ABf/f/f/f/f/f/f/HkGOGOGOGOGOHnHXf/f/f/f/f/f/f/AAf/f/f/f/f/ABf/f/f/f/f/f/f/DiDjDkCqCqCqCqCqCqCq
BOARD 0 3 64 0 FCFCFCHdHeHfJCJDJ9f/AAf/f/f/f/f/f/f/f/f/f/f/f/f/f/HkGOGOGOGOGOGOHnHXf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/DSDTDUCqCqCqCqCqCqCq
BOARD 0 4 64 0 FCFCFCHNHOHPIyIzJtf/f/f/f/f/AAf/f/f/f/f/f/f/f/ABf/HkGOH1H0GOGOGOGOG7f/f/f/AAf/f/f/f/f/AAf/f/f/f/f/f/f/f/f/f/DiDjDkCqCqCqCqCqCqCq
BOARD 0 5 64 0 FCFCFCHdHeHfJCJDJ9f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/GmGWGOGOGOGOGOGOG7f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/DSFhC4F9CqCqCqCqCqCq
BOARD 0 6 64 0 FCFCFCHNHOHPIyIzJtf/f/f/f/f/f/f/f/ABf/f/AAf/f/f/f/H/GmGWGOGOGOGOGOG7f/f/f/f/f/f/f/f/ABf/f/f/f/f/f/f/f/f/f/f/DiDYFxC4F9CqCqCqCqCq
BOARD 0 7 64 0 FCFCFCHdHeHfJCJDJ9f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/GmGWGOGOGOGOHnHXf/f/f/f/f/f/DmDnH/f/f/f/f/f/f/f/f/f/f/GQGAGBDIC4F9CqCqCqCq
BOARD 0 8 64 0 FCFCFCHNHOHPIyIzJtf/f/f/f/f/AAf/f/f/f/f/f/f/f/f/f/f/f/f/GmGWGOGOGOGOHnHXf/f/f/AAf/D2D3Dnf/f/f/f/f/f/f/f/f/f/f/GQGRDYFxC4F9CqCqCq
BOARD 0 9 64 0 FCFCFCHdHeHfJCJDJ9f/f/f/f/f/f/f/f/f/f/f/f/ABf/f/f/f/f/ABf/GmGWGOGOGOGOHnHXH/f/f/f/CmCnD3CpCpDnf/f/f/f/f/f/f/f/f/GQGAGBGNDUCqCqCq
BOARD 0 10 64 0 FCFCFCHNHOHPIyIzJtf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/GmGWGOGOGOGOHnHXf/f/f/C2C3C4C5C6D3Dnf/f/f/f/f/f/f/ABf/GQGRJCDkCqCqCq
BOARD 0 11 64 0 FCFCFCHdHeHfJCJDJ9f/f/f/f/ABf/f/f/f/AAf/f/f/f/f/AAf/f/f/f/f/f/GmGWGOH1H0GOG7f/f/f/f/DHDIDJDKC4D3CpCpCpCpDnf/f/f/f/AADSDTDUCqCqCq
BOARD 0 12 64 0 FCFCFCHNHOHPIyIzJtf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/GmGWGOGOG3HHf/f/f/f/DXDYDZDaFxC4C5C6C5C6D3Dnf/f/f/DwDiDjDkCqCqCq
BOARD 0 13 64 0 FCFCFCHdHeHfJCJDJ9f/AAf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/ABf/H/GmH2H3HHH/f/f/f/f/H/DoDpDqGBDIDJDKDJDKC4D3Dnf/DwDxDyDzC1CqCqCq
BOARD 0 14 64 0 FCFCFCHNHOHPIyIzJtf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/ABf/f/H/D4D5D6GRDYDZDaDZDaFxC4D3DnDxDyDzC1CqCqCqCq
BOARD 0 15 64 0 FCFCFCHdHeHfJCJDJ9f/f/f/f/f/f/f/f/ABf/f/f/f/f/f/f/f/f/AAf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/GQGADpDqDpDqGBDIC4D3DSDTDUCqCqCqCqCq
BOARD 0 16 64 0 FCFCFCHNHOHPIyIzJtf/f/f/f/f/f/f/f/f/f/f/f/f/f/AAf/f/f/f/f/f/f/f/f/ABf/f/AAf/f/f/f/f/f/f/f/f/f/GQD5D6D5D6GRDYFxC4DiDjDkCqCqCqCqCq
BOARD 0 17 64 0 FCFCFCHdHeHfJCJDJ9f/f/f/f/f/AAf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/GQGAGBGNEUDTDUCqCqCqCqCq
BOARD 0 18 64 0 FCFCFCHNHOHPIyIzJtf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/AJAKALAMANAOAJAKALAMANAOAJAKALAMANAOAJAKALAMANAOf/f/GQGRJCEkDjDkCqCqCqCqCq
BOARD 0 19 64 0 FCFCFCHdHeHfJCJDJ9f/f/f/f/f/f/f/f/f/f/f/f/ABf/f/f/f/AYYHYIYIYIYIYJAZAaAbAcAdAeAZAaAbAcAdAeAZAaAbAcAdAeAff/f/DSDTEUDTDUCqCqCqCqCq
BOARD 0 20 64 0 FCFCFCHNHOHPIyIzJtf/f/f/f/f/f/f/ABf/f/f/f/f/f/f/f/f/AoYXYYYcYcYYYZApAqArAsAtAuApAqArAsAtAuApAqArAsAtAuAvf/f/DiDjEkDjDkCqCqCqCqCq
BOARD 0 21 64 0 FCFCFCHdHeHfJCJDJ9I5f/f/f/f/f/f/f/f/AAf/f/f/f/f/f/f/A4YXYZHIH6YXYZA5A6A7A8A9A+A5A6A7A8A9A+A5A6A7A8A9A+A/f/f/DSDTEUDTDUCqCqCqCqCq
BOARD 0 22 64 0 FCFCFCHNHOHPFhC4I3I4I5f/f/AAf/f/f/f/f/f/f/f/f/f/f/f/BIYXYZHJG5YXYZBJBKBLBMBNBOBJBKBLBMBNBOBJBKBLBMBNBOBPf/f/DiDjEkDjDkCqCqCqCqCq
BOARD 0 23 64 0 FCFCFCHdHeGADYFxC4I3I4f/f/f/f/f/f/f/f/f/f/f/f/ABf/f/BYYKYLTnToYKYLBZBaBbBcBdBeBZBaBbBcBdBeBZBaBbBcBdBeBff/f/DSDTEUFhC4F9CqCqCqCq
BOARD 0 24 64 0 FCFCFCI0I1I2GAGBDIIzJtf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/BoBpBqTnToBtBuBpBqBrBsBtBuBpBqBrBsBtBuBpBqBrBsBtBuBvf/f/DiDjEkDYFxC4C5C6C5C6
BOARD 0 25 64 0 FCFCFCFCI0I1I2GADYJDJ9f/f/f/f/f/f/f/f/f/AAf/f/f/f/f/B4B5B6TnToB9B+B5B6B7B8B9B+B5B6B7B8B9B+B5B6B7B8B9B+B/f/f/DSFhH+GAGBDIDJDKDJDK
BOARD 0 26 64 0 FCFCFCFCFCHNHOHPDTIzJtf/f/f/f/f/f/ABf/f/f/f/f/f/f/IAIBCJCKTnToCNCOCJCKCLCMCNCOCJCKCLCMCNCOCJCKCLCMCNCOf/f/f/DiDYFxH+GRDYDZDaDZDa
BOARD 0 27 64 0 FCFCFCFCFCHdHeHfDjJDJ9f/f/f/f/f/f/f/f/f/f/f/f/f/f/IQIRf/CaT3T4Cdf/f/CaCbCcCdf/f/CaCbCcCdf/f/CaCbCcCdf/f/f/f/GQGAGBDIH+GADpDqDpDq
BOARD 0 28 64 0 FCFCFCFCFCHNHOHPDTIzJtf/f/f/AAf/f/f/f/AAf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/ACADf/f/f/f/f/f/f/f/f/f/f/H/GQGRDYFxH+H8H9H8H9
BOARD 0 29 64 0 FCFCFCFCFCHdHeHfDjJDJ9f/f/f/f/f/ABf/f/f/f/f/f/f/f/f/f/f/f/AAf/f/ACADf/f/f/f/f/f/f/ASATf/f/f/F2FnFmF3f/f/f/f/AAf/GQGAGBDIDJDKDJDK
BOARD 0 30 64 0 FCFCFCFCFCHNHOHPDTIzJtf/f/f/f/f/f/f/f/f/f/f/PzP0f/f/ABf/f/f/f/f/ASATf/f/f/f/f/ABf/f/f/f/f/F2GGAIEtGXACADf/f/f/f/H/GQGRDYDZDaDZDa
BOARD 0 31 64 0 FCFCFCFCFCHdHeHfDjJDJ9f/f/f/f/f/f/f/f/f/f/f/PAPBf/f/f/f/f/f/f/f/f/f/f/f/f/ACADf/f/f/f/f/f/GnAICrFoFpASATf/f/f/f/f/f/GQGADpDqDpDq
BOARD 0 32 64 0 FCFCFCFCFCHNHOHPDTIzJtf/f/f/f/f/f/f/f/f/f/f/PQPRf/f/f/f/f/f/f/f/f/f/f/f/f/ASATf/f/f/f/f/f/GIF4F5Fpf/f/f/f/f/f/f/f/ABH/GQD5D6D5D6
BOARD 0 33 64 0 FCFCFCFCFCHdHeHfDjJDJ9f/f/f/f/AAf/f/f/f/f/f/PgPhf/f/f/f/f/f/f/f/f/f/AAf/f/f/f/f/ACADf/f/ACADf/f/ACADf/f/f/f/f/f/f/f/f/f/f/f/f/f/
BOARD 0 34 64 0 FCFCFCFCFCHNHOHPIyIzJtf/ABf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/ABf/f/f/f/f/f/f/f/ASATACADASATACADASATf/f/f/f/f/AAf/f/f/f/f/f/f/f/
BOARD 0 35 64 0 FCFCFCFCFCHdHeHfJCJDJ9f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/F2FmF3AAf/ASATf/f/ASATf/f/f/f/ABf/f/f/f/f/f/f/f/f/f/f/
BOARD 0 36 64 0 FCFCFCFCFCHNHOHPIyIzJtf/f/f/f/f/PzP0f/f/f/f/f/f/f/f/f/f/PzP0f/f/f/f/f/F2FmGGCrGXf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/
BOARD 0 37 64 0 FCFCFCFCFCHdHeHfJCJDJ9f/f/f/f/f/PAPBf/f/f/f/f/f/f/f/f/f/PAPBf/f/f/F2FmGGCrCqCqGHFmFnFmFnFmF3f/f/f/f/f/F2FmFnFmFnF3f/f/AAf/f/f/f/
BOARD 0 38 64 0 FCFCFCFCFCHNHOHPIyIzJtf/f/f/f/f/PQPRf/f/f/f/OzO0f/f/f/f/PQPRf/f/f/GnAICqCqCqCqCqEtCqAPCrEtGHFmF3F2FnFmGGCrAIAPAIGHF3f/f/f/f/f/f/
BOARD 0 39 64 0 FCFCFCFCFCHdHeHfDjJDJ9f/f/f/f/f/PgPhf/f/f/f/OzO0f/f/f/f/PgPhf/F2FmGGAPCqAPCrCqCqEtCqCqCqCqAICqGHGGAICrAPCqCqCqCqCrGXf/f/f/AAf/f/
BOARD 0 40 64 0 FCFCFCFCFCHNHOHPDTIzJtf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/GnAPEtCqEtEtCqEtEtCrCrCqCrEtAICrEtCqCqAPCqCqCqAIEtFoFpABf/f/f/f/f/
BOARD 0 41 64 0 FCFCFCFCFCHdHeHfDjJDJ9f/f/f/f/AAf/f/f/f/f/f/f/f/f/f/f/AAf/f/f/GIF4F5F4F5GJCqCqCqCqCqCqCqCqCqCqCqCqCqCqCrAIAIFoF5Fpf/f/f/f/f/f/f/
BOARD 0 42 64 0 FCFCFCFCFCHNHOHPDTIzJtf/ABf/f/f/f/f/AAf/f/f/f/f/ABf/f/f/P/f/f/f/f/f/f/f/GIF5GJAICqCrAICqCqEtAIAPCqEtCqFoF4F5Fpf/f/f/f/f/f/f/f/f/
BOARD 0 43 64 0 FCFCFCFCFCHdHeHfDjJDJ9f/f/f/f/ABf/f/f/f/f/f/PzP0f/f/f/f/f/f/f/f/AAf/f/f/f/f/GIF5F4F5GJEtAICqCrFoF4F5F4Fpf/f/f/f/f/f/f/f/f/f/f/f/
BOARD 0 44 64 0 FCFCFCFCFCHNHOHPDTIzJtf/f/f/f/f/AAf/f/f/f/f/PAPBf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/GIF5F4F5F4Fpf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/
BOARD 0 45 64 0 FCFCFCFCFCHdHeHfDjJDJ9f/f/ABf/f/f/f/f/f/f/f/PQPRf/f/ABf/f/ABf/f/f/f/f/E0KOKPKOKPKOKPKOKPKOKPKOKPKOKPKOKPKOKPKOKPKOKPKOKPKOKPKOKP
BOARD 0 46 64 0 FCFCFCFCFCHNHOHPIyIzJtf/f/f/f/f/f/f/f/f/f/f/PgPhf/f/f/f/f/f/f/f/f/f/E0E1KeKfKeKfKeKfKeKfKeKfKeKfKeKfKeKfKeKfKeKfKeKfKeKfKeKfKeKf
BOARD 0 47 64 0 FCFCFCFCFCHdHeHfJCJDJ9f/f/f/f/f/AAf/f/f/f/f/f/f/f/f/f/f/P/f/f/f/f/E0E1E2C5C6C5C6C5C6C5C6C5C6C5C6C5C6C5C6C5C6C5C6C5C6C5C6C5C6C5C6
BOARD 0 48 64 0 FCFCFCFCFCHNHOHPIyIzJtf/f/ABf/f/f/f/f/f/AAf/f/f/f/f/f/f/f/f/f/f/E0E1E2C7DJDKDJDKDJDKDJDKDJDKDJDKDJDKDJDKDJDKDJDKDJDKDJDKDJDKDJDK
BOARD 0 49 64 0 FCFCFCFCFCHdHeHfJCJDJ9f/f/f/f/f/f/ABf/f/f/f/f/f/f/f/f/AAf/f/f/E0E1E2C7DeDZDaDZDaDZDaDZDaDZDaDZDaDZDaDZDaDZDaDZDaDZDaDZDaDZDaDZDa
BOARD 0 50 64 0 FCFCFCFCFCHNHOHPIyIzJtf/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/E0E1E2C7DLDuDpDqDpDqDpDqDpDqDpDqDpDqDpDqDpDqDpDqDpDqDpDqDpDqDpDqDpDq
BOARD 0 51 64 0 FCFCFCFCFCHdHeHfJCJDJ9f/f/f/f/f/f/f/f/f/f/f/f/f/ABf/f/f/f/E0E1E2C7DeDbD+IuIvIuIvIuIvIuIvIuIvIuIvIuIvIuIvIuIvIuIvIuIvIuIvIuIvIuIv
BOARD 0 52 64 0 FCFCFCFCFCHNHOHPIyJDJ9I5f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/f/E0E1E2C7DLDuDvEmI+I/I+I/I+I/I+I/I+I/I+I/I+I/I+I/I+I/I+I/I+I/I+I/I+I/I+I/
BOARD 0 53 64 0 FCFCFCFCFCHNHOHPGtC4I3I4KOKPKOKPKOKPKOKPKOKPKOKPKOKPKOKPE1E2C7DeDbD+EmEnJOJPJOJPJOJPJOJPJOJPJOJPJOJPJOJPJOJPJOJPJOJPJOJPJOJPJOJP
BOARD 0 54 64 0 FCFCFCFCFCHdHeHfDYFxC4I3KeKfKeKfKeKfKeKfKeKfKeKfKeKfKeKfE2C7DLDuDvEmEnEoFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC
BOARD 0 55 64 0 FCFCFCFCFCI0I1I2GAGBDIC4C5C6C5C6C5C6C5C6C5C6C5C6C5C6C5C6C7DeDbD+EmEnEoFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC
BOARD 0 56 64 0 FCFCFCFCFCFCI0I1I2GAGBDIDJDKDJDKDJDKDJDKDJDKDJDKDJDKDJDKDeDuDvEmEnEoFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC
BOARD 0 57 64 0 FCFCFCFCFCFCFCI0I1I2GAGBDZDaDZDaDZDaDZDaDZDaDZDaDZDaDZDaDuDvEmEnEoFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC
BOARD 0 58 64 0 FCFCFCFCFCFCFCFCI0I1I2GADpDqDpDqDpDqDpDqDpDqDpDqDpDqDpDqDvEmEnEoFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC
BOARD 0 59 64 0 FCFCFCFCFCFCFCFCFCI0I1I2IuIvIuIvIuIvIuIvIuIvIuIvIuIvIuIvEmEnEoFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC
BOARD 0 60 64 0 FCFCFCFCFCFCFCFCFCFCI0I1I+I/I+I/I+I/I+I/I+I/I+I/I+I/I+I/EnEoFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC
BOARD 0 61 64 0 FCFCFCFCFCFCFCFCFCFCFCI0JOJPJOJPJOJPJOJPJOJPJOJPJOJPJOJPEoFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC
BOARD 0 62 64 0 FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC
BOARD 0 63 64 0 FCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFCFC
LINK d2a2010-b2.nw 63 0 1 64 0 playery
LINK d2a2010-bm2.nw 0 0 64 1 playerx 61
SIGN 25 27

#u Shrine
SIGNEND
NPC - 21 11
// invisible NPC sets music and map
if (playerenters) {enableweapons;
//play d.mid;
setminimap dmap2.png,map-d2a2010.txt,1,56;
setmap d2a2010-map-ow.png,map-d2a2010.txt,1,56;
puthorse goodride.gif,40,40;}
if (playertouchsme) {
}
NPCEND


I'd like to get some thoughts from Christopho and other Solarus developers to figure out how to get this to work, since I'm not sure where to begin.

The level format of Graal seems simple and documented, so it should be easy to write a converter to Solarus maps and tilesets.

Some research has turned up a Python-based converter available on GitHub which can write Graal levels to PNG images or (more usefully) Tiled map editor's TMX format.

https://github.com/Aeva/nw-converter

After struggling for a while to understand Python well enough to make it work (a directory named "out" needs to exist, which isn't in the readme), it looks like a quick Solarus converter can be forked from it. I might try to write one myself, but my programming skills are very crude and it might take me a while to figure out how to plot out a good approach. Ideally, a good converter would be able to notice lines or blocks of repeating tiles and change them to a single resized tile for Solarus. But I'd just settle for translating the entire grid of 4096 tiles to a 512x512-sized Solarus map.

This doesn't address how to actually get the Tileset itself setup in the Solarus quest editor though. While the scale of the image is twice the size of a typical Solarus tileset, that's fixable with some photo editing. The bigger problem is that once it's properly shrunk the whole thing amounts to 4096 patterns in all, which would take forever to do by hand. There's got to be some way to automate this as well.

February 05, 2017, 02:10:25 AM #3 Last Edit: February 05, 2017, 02:21:19 AM by ffomega
The original creator of Graal actually became a member of this forum not too long ago, and even reached out to Chris about Solarus :)

Also, on the topic of converters, someone once created a level generator for Graal (as I used it all the time).  It converted a png containing simple shapes and specific colors similar to how regions work in RPG maker, and converted that image into a Graal level, or depending on the size of the bitmap, a series of connected maps.

http://www.graal.net/index.php/Creation/Dev/Level_Generator
(if anyone is interested, I have a copy of the level generator)

Could a level generator be possible with Solarus?
My tilesets page can be found here:
http://absolute-hyrule-tutorials.solarus-games.org/

The last time I checked, Stefan Knorr (Graal's creator and lead programmer) was skilled enough to be writing his own engine and was trying to get it off the ground as a Facebook game. It looks like the guy who joined this forum recently is just one of the many people who developed games using Graal as a platform, like me. It was very powerful in its heyday, and had a lot of community support and inertia behind it. A pity it was all so centralized that the whole thing could be scuttled by bad actors at the head of the business side of things.

Stefan's new game isn't really a developer platform the way Graal was. But Solarus can do nearly everything Graal was capable of in a familiar Zelda format, which is why old Graal hands like us are interested in using it. (Too bad there isn't more crossover from the Zelda Classic community as well...)


RE: level generation... if I can get an importer to work, the old Graal tool might still prove useful. It was never really that good at its job, though...

I've built a crude tool from the Python converter I linked upthread. At the moment, it spits out half-broken tmx files with the tile data reformatted to Solarus's specifications. I then used a text editor to paste that data into a Solarus map file.
I've also cobbled together an acceptable tileset to use. I haven't gone through it to set every single Pattern, but I've got some basic walls and water working. It also looks kind of weird because I had to scale it down for Solarus, and I was aiming for just getting it to work instead of making it look good.

I'd prefer not to release the converter itself until I can hack it up a bit more so it at least creates Solarus maps that can just be dropped into a quest. That way, anyone who finds this thread won't have to ask me why it's broken! (I'm still convinced that someone who knows what they're doing could create a better tool by using the information in this thread and the Solarus manual, but eh)

Here's a quick demo quest made for Solarus 1.6 if you want to see the results for yourself:

Demo quest
There are two converted levels here. Leave through the door in the starting area to see the first one, and go to the North edge of the screen from there to see the second.

I do think that the only real advantage of doing this at all is when you want to import your old Graal levels without having to re-build them from scratch. Anyone who wants to create new material would have better luck just using the Solarus editor normally.

Cool! It could be integrated into Solarus Quest Editor.

February 06, 2017, 02:29:38 AM #7 Last Edit: February 06, 2017, 02:38:07 AM by Zaidyer
Quote from: Neovyse on February 05, 2017, 11:03:43 PM
Cool! It could be integrated into Solarus Quest Editor.
Nah, I'd say the scope is too limited for that. All you get out of it is the tile grid, not any of the code or interactivity. And that being the case, it would be far more useful to write in something like support for Tiled Map Editor, which can already export to Lua.

Besides that, having the name "Graal" anywhere near an official feature list in a game engine might set off a few alarm bells at the company who owns it. That's not what this thread is about.