Procedural map generation

Everything related to modding, mapping and software or hacks

Procedural map generation

Postby zoaedk » Sat Aug 20, 2016 2:30 pm

As I was looking around the Nox code, I stumbled across the map generation stuff again. This time I actually took some time to understand it. Below are instructions for using Nox's built-in map generation.

First thing to understand is that the map generation requires a theme file. The complete syntax is a little verbose, but the sample theme file below gives you an idea. I will try to completely document the syntax later.

The theme file is encrypted, just like many other Nox files. I wrote a quick python script (https://github.com/NoxTools/noxcrypt/re ... xcrypt.exe) which you can use to encrypt theme files.

Once it is encrypted, save the theme into \mapgen\, you should load up Nox; and make sure that it is Administrator or has permissions to write to \maps\. Start a Local Network, multiplayer game, and in the console type:
Code: Select all
racoiaws
load #foobar

Obviously, you should change the foobar part to the name of your theme file. The # is what indicates that you want to generate a map instead of loading a normal map. If everything goes smoothly, you will now be in your new map and it will have been saved in your maps folder as $foobar.

Sample theme file (foobar.thm)
Code: Select all
//
// This file should be encrypted then saved in your Nox directory as \mapgen\foobar.thm. The filename determines the map name. Keep under 8 chars.
//

AMBIENT_LIGHT 255 255 255

DECOR
    ROOM foo
    FREQUENCY COMMON
    WALL_FLOOR AncientRuin AncientRuin
END

DECOR
    HALL bar
    FREQUENCY COMMON
    WALL_FLOOR AncientRuin AncientRuin
END

// End of file


Sample theme file with sample generated map is attached.
Attachments
$foobar.zip
Sample files
(175.46 KiB) Downloaded 110 times
Last edited by zoaedk on Mon Aug 22, 2016 12:57 pm, edited 1 time in total.
zoaedk
Global Moderator
Global Moderator
Posts: 42
Joined: Sat Jul 04, 2015 12:09 pm
Location: Austin, TX, USA

Re: Procedural map generation

Postby Xandros » Sat Aug 20, 2016 4:19 pm

Wait. Map generator in Nox is working??? I heard that map generator consists mostly of stubs and unfinished code chunks...
Nox Unimod scripter.
My plugins:
Advanced chat plugin.
Antiblock system
User avatar
Xandros
Novice
Posts: 128
Joined: Sun Jul 13, 2014 3:45 pm
Location: Russian Federation. Moscow.

Re: Procedural map generation

Postby zoaedk » Sun Aug 21, 2016 5:25 am

I previously thought that it was hopeless as well. But apparently I just wasn't good enough previously to understand how it works.

That said, this is not sufficient for making a good map. It could be useful though to create an initial map with doors, tiles, walls, etc., which someone could then tweak and improve in the map editor.

Once I finish the scripting stuff I'm focusing on, I'll poke at this some more.
zoaedk
Global Moderator
Global Moderator
Posts: 42
Joined: Sat Jul 04, 2015 12:09 pm
Location: Austin, TX, USA

Re: Procedural map generation

Postby superjack46 » Mon Aug 22, 2016 5:12 am

By the way, KirC also implemented a map generator in the map editor. You can check it in the newest version, just press F7.

Brilliant stuff though, zoa.
WOL account: unknownle, character: Maurice Ravel, my NoX related website: http://corner.noxcommunity.com
User avatar
superjack46
Administrateur supérieur
Administrateur supérieur
Posts: 115
Joined: Fri Apr 04, 2014 2:52 pm

Re: Procedural map generation

Postby Xandros » Mon Aug 22, 2016 12:56 pm

Wow. Thank you for figuring out how it works. I will use it someday.
Nox Unimod scripter.
My plugins:
Advanced chat plugin.
Antiblock system
User avatar
Xandros
Novice
Posts: 128
Joined: Sun Jul 13, 2014 3:45 pm
Location: Russian Federation. Moscow.

Re: Procedural map generation

Postby angrykirc » Wed Aug 24, 2016 2:34 pm

just my 5 cents, some old research
Code: Select all
// 0x004D4320
BOOL __cdecl mapGenStart()
// 0x004D5F30
BOOL __cdecl mapGenStartAlt()
// 0x0051E540
BOOL __cdecl mapGenReadLine(FILE *File, char *out)
// 0x0051E260
BOOL __cdecl mapGenReadTheme(mapGenTheme *data, char *configFile)
// 0x004D44E0
BOOL __cdecl mapGenStep()
// 0x00526AC0
int __cdecl mapGenRandFunc(int min, int max)
//0x00521A40
void __cdecl mapGenFreeTopRoom()
// 0x00521710
mapGenWorkRoom *__cdecl mapGenGetTopRoom()
// 0x00521940
mapGenWorkRoom *__cdecl mapGenMakeRoomStruct(signed int x, signed int y)
// 0x00521730
int __cdecl mapGenAddNewRoom(mapGenWorkRoom *newr)
// 0x00526830
BOOL __cdecl mapGenPlacePrefabs(mapGenTheme *theme)
// 0x00524310
BOOL __cdecl mapGenMakeRooms(mapGenTheme *theme)
// 0x00522A40
BOOL __cdecl mapGenMakeExit(mapGenTheme *theme)
// 0x00521990
mapGenWorkRoom *__cdecl mapGenPrepareRoom(mapGenTheme *theme)
// 0x004D4F40
mapGenWorkRoom *__cdecl mapGenMkSmallRoom(mapGenTheme *theme)
// 0x00521880
mapGenWorkRoom *__cdecl mapGenSetRoomPos(mapGenWorkRoom *room, float *coords)
// 0x00521850
mapGenWorkRoom *__cdecl mapGenUpdateRoomRect(mapGenWorkRoom *room)
// 0x005238F0
BOOL __cdecl mapGenCheckRoomType(mapGenWorkRoom *room)
// 0x005220E0
bigUnitStruct *__cdecl mapGenMakeSpellbook(mapGenTheme *theme, const char *name)
// 0x00522810
bigUnitStruct *__cdecl mapGenMakeMonsterInRoom(mapGenWorkRoom *room, char *name)
// 0x00527940
BOOL __cdecl mapGenGetObjID(char *Key)
// 0x005279B0
bigUnitStruct *__cdecl mapGenPlaceObj(float *coords)
// 0x00527A10
bigUnitStruct *__cdecl mapGenMoveObject(bigUnitStruct *Unit, float *coords)
// 0x00527C60
BOOL __cdecl mapGenOrientObj(bigUnitStruct *obj, int dir)
// 0x004D3D90
BOOL __cdecl mapGenFixCoords(float *a1, float *a2)


// 0x0074EB78 mapGenTheme (full struct)
// 0x00833A9C mapGenWorkRoom*
// 0x0074EFD4 mapGenWorkRoom*
// 0x0074EFD8 mapGenWorkRoom*
// 0x00833AAC mapGenWorkRoom*


//(sizeof=0x45C)
struct mapGenTheme
{
  int skeleton;
  int midHallLength;
  int hallLengthVariance;
  int midHallWidth;
  int hallWidthVariance;
  int hallLimit;
  int hallBranchRate;
  int hallRoomRate;
  int midRoomSize;
  int roomVariance;
  int irregularRoomRate;
  int emptyRoomRate;
  int mergeRate;
  int adjacentPortalRate;
  int useDoors;
  int debug;
  int mapSize;
  float smallMapSize;
  int recursionLimit;
  int seed;
  int prefabStructPtr;
  int prefabCounter;
  mapGenDecorStruct *roomDecorStruct;
  int roomDecorCounter;
  char unkBlock1[24];
  mapGenDecorStruct *hallDecorStruct;
  int hallDecorCounter;
  char unkBlock2[24];
  mapGenDecorStruct *templateDecorStruct;
  int templateDecorCounter;
  char unkBlock3[24];
  mapGenDecorStruct *backdropDecorStruct;
  int backdropDecorCounter;
  char unkBlock4[24];
  char mapExitA[64];
  char mapExitB[64];
  char mapExitC[64];
  char mapExitD[64];
  char mapExitE[64];
  int ambLightR;
  int ambLightG;
  int ambLightB;
  int spellList[137];
  int spellListCounter;
  int lastWeaponSet;
  int weaponSetCounter;
  int lastArmorSet;
  int armorSetCounter;
};


//(sizeof=0xE0)
struct mapGenDecorStruct
{
  char decorTypeStr[60];
  int decorTypeId;
  char occurConstraint;
  char occurLimit;
  char unknownBool;
  char decorMustOccur;
  char generated;
  char unusedAlign1;
  char unusedAlign2;
  char unusedAlign3;
  int frequency;
  int roomSizeMin;
  int roomSizeMax;
  mapGenWallFloorData *wallFloorDataPtr;
  int wallFloorCounter;
  mapGenDecorSetData *decorSetDataPtr;
  int decorSetCounter;
  char doorThingName[60];
  char doubleDoorThingName[60];
  mapGenDecorStruct *prevStructPtr;
};


//(sizeof=0x80)
struct mapGenWallFloorData
{
  char wallTypeStr[60];
  char floorTypeStr[60];
  int unused;
  mapGenWallFloorData *prevStructPtr;
};


//(sizeof=0x18)
struct mapGenDecorSetData
{
  int int1;
  int int2;
  mapGenDecorElement *lastElement;
  int elementCounter;
  int unknown1;
  int unknown2;
};


//(sizeof=0x64)
struct mapGenDecorElement
{
  int elementTypeId;
  char unkString[60];
  int unkBool;
  int unkCount;
  int unkInt2;
  float unkFloat;
  int unused1;
  int unused2;
  mapGenDecorElement *prevElementPtr;
  int unused3;
  int unused4;
};


//(sizeof=0x9C)
struct mapGenWeaponArmorSet
{
  char string1[60];
  char string2[60];
  int unknown1;
  int unknown2;
  int unknown3;
  int unknown4;
  int unknown5;
  int unknown6;
  int unknown7;
  int unknown8;
  mapGenWeaponArmorSet *prevStructPtr;
};


//(sizeof=0x178)
struct mapGenWorkRoom
{
  int type;
  int wallPosX;
  int wallPosY;
  int wallSizeX;
  int wallSizeY;
  float fltPosX;
  float fltPosY;
  float sizeX;
  float sizeY;
  float fltRectX;
  float fltRectY;
  float fltRectRight;
  float fltRectDown;
  char unknown1[16];
  int flags;
  mapGenWorkRoom *prevRoom;
  mapGenWorkRoom *nextRoom;
  char unknown2[20];
  mapGenWorkRoom *branchMb;
  char unknown3[128];
  char unkArray[4];
  char unknown4[156];
};
User avatar
angrykirc
Initiate
Initiate
Posts: 15
Joined: Thu Jul 10, 2014 3:34 pm


Return to Modding & Mapping

Who is online

Users browsing this forum: No registered users and 5 guests

cron