Register - Login
Views: 99407688
Main - Memberlist - Active users - Calendar - Wiki - IRC Chat - Online users
Ranks - Rules/FAQ - Stats - Latest Posts - Color Chart - Smilies
04-24-22 08:30:23 PM
Jul - General Game/ROM Hacking - Chronicles of Hacking The Lemmings Chronicles New poll - New thread - New reply
Next newer thread | Next older thread
GuyPerfect
Catgirl
Level: 68


Posts: 407/1096
EXP: 2663587
For next: 65213

Since: 07-23-07


Since last post: 1.6 years
Last activity: 211 days

Posted on 04-23-08 01:39:25 AM (last edited by GuyPerfect at 04-23-08 11:38 PM) Link | Quote
Not exactly ROM hacking, per sé, as this is a PC game, but this is probably the best spot for it. I'm hacking The Lemmings Chronicles because I thought it'd be fun and easy to do. It is both fun and easy to do.


Tribe IDs

Three of the twelve Lemmings tribes are in this game: Classic, Shadow and Egyptian. The game seems to be structured in a way that adding more tribes may simply be a matter of adding in more files. We'll see over time.

As far as level editing is concerned, there are a few identifiers used to determine tribe:
- 001 = Classic
- 002 = Shadow
- 003 = Egyptian

The graphics, on the other hand, use these identifiers:
- 004 = Classic
- 010 = Shadow
- 005 = Egyptian

Don't worry about that second list for now. They're not important to level editing.


Palette

First thing you're gonna need to do to display a stage is load its palette.
- Palettes contain 256 entries.
- Part of the palette is dedicated solely to the Lemmings themselves and stored in their respective .IND files. I haven't hacked those yet.
- Part of the palette is loaded from GRAPHICS\GAME.PAL. This is probably for common things that never change color.
- The rest of the palette is loaded from STYLES\DATA***.PAL. This is the file I'm gonna be documenting at this time.

There are three DATA***.PAL files in the STYLES directory; one is loaded depending on which tribe you're playing as. Use the first identifier list to determine which palette file to use for your tribe.

Palettes in the game are stored as arrays of color values in the format RGB24 (one byte for each channel). The DATA***.PAL files each contain 208 palette entries, but there's a catch:
- The first 64 entries (offsets 0x0000 to 0x00BF) have unknown significance at this time. They seem to be normalized between 0 and 255.
- The remainder of the file contains 144 palette entries that are loaded sequentially starting at palette index 0x60. The values, for whatever reason, need to be multiplied by 4 when loaded... Sometimes it's best to not ask questions.


Stage Block Definitions

The stages need to have graphics and such to be useable, right? These are stored in the STYLES directory in the following files:
- PERM***.OBJ
- PERM***.FRL
- PERM***.BLK
- TEMP***.OBJ
- TEMP***.FRL
- TEMP***.BLK

"PERM" is short for "permanent," but that's not very descriptive of what those objects do. PERM objects can really be described as anything that isn't directly stage data. This can be traps, items, exits, etc.

"TEMP" is "temporary," but is actually anything having to do with something a Lemming can step on. Some surfaces can be destroyed, others disintegrate, and some are rock hard, but if a Lemming interacts with it, it's a TEMP object.

Object Definition Files
The .OBJ files include arrays of data used to describe the objects used in the stages.
- The total number of entries is arbitrary and is calculated directly from the file size.
- Each entry consists of 15 bytes.

0x0 UINT16 - Block ID
These are sequential for the most part, but their location can vary. They are used by the game to link up an object used in a stage with its definition. Kinda sloppy, but it allows easy moving of data in different parts of the file.

0x2 UINT16 - (Unknown A)
The significance of this element is not known at this time.

0x4 UINT16 - Block Definition FRL Offset
The offset of the block's actual tile definition in the corresponding .FRL file.

0x6 UINT16 - (Unknown B)
The significance of this element is not known at this time.

0x8 BYTE - Block Tile Width
0x9 BYTE - Block Tile Height

The tile width and height of the object. Probably used for memory allocation.

0xA UINT16 - (Unknown C)
0xC UINT16 - (Unknown D)

The significance of these elements is not known at this time.

0xE BYTE - Terminator
A terminator. Is this really needed? Must be 0.


Block Definition Files
The .FRL files include chunks of data used to describe the exact construction of objects.
- The data is referenced indirectly, so it's impossible to parse without the corresponding .OBJ file.

When a .OBJ file defines an object, it will link into the .FRL file with the following entries:
0x0 UINT16 - Internal Data Offset
This might have been intended for an indexing setup at one time or other, but now it's just redundant data. This entry points to another location in the .FRL file.

Once redirected, there's another kind of data entry in the .FRL file that describes the object:
0x0 BYTE - Structure Type
There are two ways that the game can build stage objects, and they are identified with this file:
- 0x00 = Data is built manually by specifying the tile X and Y coordinates before linking to the pixel data.
- 0x01 = The pixel data is linked to directly to completely fill the rectangular region specified by the object definition.

0x1 UINT16 Tile Count
Specifies the number of tiles used to describe the object. Used for allocating memory; x4 for Structure Type 0 and x2 for Structure Type 1.

0x3 (If Structure Type == 0) UINT16 Construction List
If the Struture Type is 0, this field will be occupied with yet another redirection pointer. As before, this value specifies the location in the same .FLV where the tile coordinates and references are stored.

0x3 (If Structure Type == 1) Array.UNIT16 Tile References
If the Struture Type is 1, the data following the Tile Count element is a list of pointers referencing the tile data. There are Tile Count entries. Each entry is the offset in the .BLK file where the tile data is located.

In the event Structure Type is 0, there will be one more data entry in the .FRL file. There will be Tile Count elements of the following format:
0x0 BYTE - X Coordinate
0x1 BYTE - Y Coordinate

The X and Y coordinates of the tile used to describe the object. These are in tile coordinates, not pixel coordinates.

0x2 UINT16 Tile BLK Offset
The offset in the .BLK file where the tile data is located.

Tile Definition Files
The .BLK files contain raw pixel data used to define the graphical appearence of stage objects.
- The data is referenced indirectly, so it's impossible to parse without the corresponding .FRL file.
- Only the tile index is referenced. Since each tile is 16 bytes, multiply the index by 16 to get the file offset of the tile.
- Unlike most systems, the dimensions of one tile are 8x2 pixels.
- Each tile is specified with 16 bytes:

Each byte specifies the palette index of the color to be used.

Let's say that the 16 bytes in a tile definition are labeled thusly:

0 1 2 3 4 5 6 7 8 9 A B C D E F

That said, the pixels of the tile are defined by rearranging the bytes in this order:

0 4 8 C 1 5 9 D
2 6 A E 3 7 B F


Level Data

With the fancy graphics out of the way, we need to know what to do with them in order to successfully build a stage, don't we? Stages are stored in the LEVELS directory in the following files:
- LEVEL***.DAT
- PERM***.OBS
- TEMP***.OBS

In this case, the *** specifies which stage the game loads:
- 001 to 030 = Classic levels
- 101 to 130 = Shadow levels
- 201 to 230 = Egyptian levels
- 400 to 999 = (Haven't investigated these yet. Likely tutorials and the practice stage)

Level Meta Files
The .DAT files specify all the meta information of a stage before it's actually loaded into memory.
- The file consists of one entry exaclty 30 bytes long:

0x00 UINT16 Tribe ID
Specifies which tribe file to load. Use the second list (4, 10, 5) to pick a tribe. Links to GRAPHICS\TRIBE***.IND

0x02 UINT16 (Unused A)
0x04 UINT16 (Unused B)

Not used in any of the stages, but might still retain their functionality. They link to GRAPHICS\CAVE***.MAP and GRAPHICS\CAVE***.RAW, respectively. No CAVE files exist in that directory, however.

0x06 UINT16 PERM File ID
0x08 UINT16 TEMP File ID

Specify which PERM***.OBS and TEMP***.OBS file to use.

0x0A UINT16 (Unknown A)
The significance of this element is not known at this time.

0x0C UINT16 Stage Width
0x0E UINT16 Stage Height

Specifies the width and height of the stage, in pixels. Objects can be placed out of bounds, but extranneous pixels will not be retained.

0x10 UINT16 Default Camera Left
0x12 UINT16 Default Camera Top

Specify the current location of the camera. Should not place any part of the viewport out of bounds. The viewport's dimensions are 320x160 pixels.

0x14 UINT16 Starting Time
The value of the timer when the stage is loaded. Time format is not known, but is assumed to be an integral number of seconds.

0x16 UINT16 (Unknown B)
The significance of this element is not known at this time.

0x18 UINT16 Lemming Drop Rate
0x1A UINT16 Lemming Drop Delay

Determine how fast Lemmings drop from the starting gates, and how much time ellapses before they begin to drop. The time format for these is currently unknown, but larger values yield longer pauses.

0x1C UINT16 (Unknown C)
The significance of this element is not known at this time.

The tileset, music and palettes are selected by the game depending on which tribe you select. Why the tribe graphics themselves aren't determined in this manner is a mystery.

Level Obstacle Files
Both the PERM***.OBS and TEMP***.OBS files share the same format and define the stages by placing objects in them.
- The number of elements in the file is calculated directly on the file size.
- Objects are drawn in the order they appear, and the PERM layer comes before the TEMP layer.
- Each element consists of six bytes:

0x0 UINT16 Object ID
Specifies the object to be placed. May be used for background panels, stage surfaces, items, enemies, traps, etc.

0x2 INT16 X Coordinate
0x4 INT16 Y Coordinate

The X and Y coordinates of the object, in pixels. These appear to be signed values, though this hasn't been tested.

Special Object IDs
While the Object ID entry of the PERM obstacle file corresponds for the most part with graphical objects defined in the .OBJ files, there are some special values that determine other kinds of objects defined in the game's programming.

This is an incomplete list:
- 96 00 = Forest eyeballs (white)
- 16 27 = Lemming
- 88 13 = Builder Item
- 89 13 = Bomber Item
- 8A 13 = Digger Item
- 8B 13 = Hadouken Item
- 8C 13 = Climber Item
- 8D 13 = Floater Item
- 8E 13 = Shimmer Item
- 8F 13 = Timer Item
- 90 13 = Swimmer Item
- 91 13 = Grenadier Item


Conclusion

I never did like conclusions, so here's a picture:

Kles

Level: 87


Posts: 1165/1947
EXP: 6306975
For next: 85799

Since: 07-23-07


Since last post: 69 days
Last activity: 16 hours

Posted on 04-23-08 10:29:53 AM Link | Quote
I'm not a TLC player, but this looks good. I'm wondering about that picture at the bottom; was it drawn using a program that reads TLC files and then draws the level layout?

Or something else?

____________________
This is my damned signature.

Onions, baby! Onions!


GuyPerfect
Catgirl
Level: 68


Posts: 410/1096
EXP: 2663587
For next: 65213

Since: 07-23-07


Since last post: 1.6 years
Last activity: 211 days

Posted on 04-24-08 12:50:17 AM (last edited by GuyPerfect at 04-23-08 11:54 PM) Link | Quote
I have an answer for you, Kles, but I'm not entirely sure how to say it. After all, I made this big long document about how to load stage data--pixels and all--and followed it up with a picture.

Yes, it was done with software that loads the level files and draws them to the screen. I programmed it myself as an application of the document that precedes it.

----------

I wrote a new program from scratch today. The old one kept getting patched as I figured things out, but the new one was written from the ground up to make organized sense of everything I've learned.

Turns out that there are little icons for special objects in the stages. When you place a Lemming, there's an icon showing which direction it will walk. The same goes for enemies in the game. Icons that may never have been seen again had I not hacked the game!

Anyhow, the new setup allowed me to apply the background layer as well, so enjoy:

YouTube video of this stage

Xkeeper

Level: 263


Posts: 5428/25343
EXP: 296733869
For next: 2226584

Since: 07-03-07

Pronouns: they/them/????????

Since last post: 9 days
Last activity: 3 days

Posted on 04-24-08 06:51:26 PM Link | Quote

"PERM" is short for "permanent," but that's not very descriptive of what those objects do. PERM objects can really be described as anything that isn't directly stage data. This can be traps, items, exits, etc.

"TEMP" is "temporary," but is actually anything having to do with something a Lemming can step on. Some surfaces can be destroyed, others disintegrate, and some are rock hard, but if a Lemming interacts with it, it's a TEMP object.


It might be better to describe "PERM" as "Objects" and "TEMP" as "Ground". That's how it appears to be, for me, at least.

...

Your image has a transparent blotch where the door is. I'm not sure if that's normal, but it looks weird on a non-dark background.

____________________
GuyPerfect
Catgirl
Level: 68


Posts: 412/1096
EXP: 2663587
For next: 65213

Since: 07-23-07


Since last post: 1.6 years
Last activity: 211 days

Posted on 04-24-08 08:03:29 PM Link | Quote
PERM is both objects AND the background panels. TEMP is just ground, though.

And yeah, that blotch doesn't have anything drawn to it. The remaining pixels are defined somewhere else in the object's behavior itself.
Craig341
Member
Level: 18


Posts: 45/50
EXP: 25949
For next: 3948

Since: 07-25-07


Since last post: 13.0 years
Last activity: 12.9 years

Posted on 04-24-08 11:32:37 PM Link | Quote
Originally posted by GuyPerfect


Three of the twelve Lemmings tribes are in this game: Classic, Shadow and Egyptian. The game seems to be structured in a way that adding more tribes may simply be a matter of adding in more files. We'll see over time.




Yeah; the idea was to release the rest of the tribes eventually in installments, but the game didn't sell well and that idea was nixed.
Next newer thread | Next older thread
Jul - General Game/ROM Hacking - Chronicles of Hacking The Lemmings Chronicles New poll - New thread - New reply


Rusted Logic

Acmlmboard - commit 47be4dc [2021-08-23]
©2000-2022 Acmlm, Xkeeper, Kaito Sinclaire, et al.

27 database queries, 2 query cache hits.
Query execution time:  0.102214 seconds
Script execution time:  0.021855 seconds
Total render time:  0.124069 seconds


TidyHTML vomit below
line 1 column 1 - Warning: missing <!DOCTYPE> declaration
line 119 column 11 - Warning: <form> isn't allowed in <table> elements
line 118 column 10 - Info: <table> previously mentioned
line 120 column 11 - Warning: missing <tr>
line 120 column 119 - Warning: missing </font> before </td>
line 124 column 16 - Warning: plain text isn't allowed in <tr> elements
line 120 column 11 - Info: <tr> previously mentioned
line 125 column 68 - Warning: missing </nobr> before </td>
line 141 column 68 - Warning: missing </nobr> before <tr>
line 147 column 35 - Warning: missing <tr>
line 147 column 50 - Warning: missing </font> before </td>
line 148 column 37 - Warning: unescaped & or unknown entity "&id"
line 147 column 218 - Warning: missing </font> before </table>
line 149 column 35 - Warning: missing <tr>
line 149 column 50 - Warning: missing </font> before </td>
line 149 column 91 - Warning: missing </font> before </table>
line 156 column 9 - Warning: <div> isn't allowed in <table> elements
line 152 column 17 - Info: <table> previously mentioned
line 158 column 9 - Warning: missing <tr>
line 176 column 13 - Warning: missing <tr>
line 177 column 99 - Warning: unescaped & or unknown entity "&postid"
line 392 column 9 - Warning: <div> isn't allowed in <table> elements
line 152 column 17 - Info: <table> previously mentioned
line 394 column 9 - Warning: missing <tr>
line 412 column 13 - Warning: missing <tr>
line 413 column 99 - Warning: unescaped & or unknown entity "&postid"
line 415 column 309 - Warning: missing </font> before <hr>
line 417 column 735 - Warning: discarding unexpected </td>
line 422 column 9 - Warning: <div> isn't allowed in <table> elements
line 152 column 17 - Info: <table> previously mentioned
line 424 column 9 - Warning: missing <tr>
line 442 column 13 - Warning: missing <tr>
line 443 column 99 - Warning: unescaped & or unknown entity "&postid"
line 462 column 9 - Warning: <div> isn't allowed in <table> elements
line 152 column 17 - Info: <table> previously mentioned
line 464 column 9 - Warning: missing <tr>
line 482 column 13 - Warning: missing <tr>
line 483 column 99 - Warning: unescaped & or unknown entity "&postid"
line 485 column 244 - Warning: missing <tr>
line 485 column 481 - Warning: missing <tr>
line 496 column 9 - Warning: <div> isn't allowed in <table> elements
line 152 column 17 - Info: <table> previously mentioned
line 498 column 9 - Warning: missing <tr>
line 516 column 13 - Warning: missing <tr>
line 517 column 99 - Warning: unescaped & or unknown entity "&postid"
line 524 column 9 - Warning: <div> isn't allowed in <table> elements
line 152 column 17 - Info: <table> previously mentioned
line 526 column 9 - Warning: missing <tr>
line 544 column 13 - Warning: missing <tr>
line 545 column 99 - Warning: unescaped & or unknown entity "&postid"
line 556 column 17 - Warning: missing <tr>
line 556 column 17 - Warning: discarding unexpected <table>
line 559 column 35 - Warning: missing <tr>
line 559 column 50 - Warning: missing </font> before </td>
line 559 column 91 - Warning: missing </font> before </table>
line 561 column 35 - Warning: missing <tr>
line 561 column 50 - Warning: missing </font> before </td>
line 562 column 37 - Warning: unescaped & or unknown entity "&id"
line 561 column 218 - Warning: missing </font> before </table>
line 563 column 17 - Warning: discarding unexpected </textarea>
line 563 column 28 - Warning: discarding unexpected </form>
line 563 column 35 - Warning: discarding unexpected </embed>
line 563 column 43 - Warning: discarding unexpected </noembed>
line 563 column 53 - Warning: discarding unexpected </noscript>
line 563 column 64 - Warning: discarding unexpected </noembed>
line 563 column 74 - Warning: discarding unexpected </embed>
line 563 column 82 - Warning: discarding unexpected </table>
line 563 column 90 - Warning: discarding unexpected </table>
line 565 column 9 - Warning: missing </font> before <table>
line 577 column 25 - Warning: discarding unexpected </font>
line 586 column 57 - Warning: discarding unexpected </font>
line 564 column 1 - Warning: missing </center>
line 120 column 63 - Warning: <img> lacks "alt" attribute
line 125 column 19 - Warning: <td> attribute "width" has invalid value "120px"
line 125 column 93 - Warning: <img> lacks "alt" attribute
line 141 column 19 - Warning: <td> attribute "width" has invalid value "120px"
line 141 column 98 - Warning: <img> lacks "alt" attribute
line 148 column 44 - Warning: <img> proprietary attribute value "absmiddle"
line 148 column 142 - Warning: <img> proprietary attribute value "absmiddle"
line 148 column 245 - Warning: <img> proprietary attribute value "absmiddle"
line 161 column 22 - Warning: <img> lacks "alt" attribute
line 161 column 63 - Warning: <img> lacks "alt" attribute
line 161 column 112 - Warning: <img> lacks "alt" attribute
line 161 column 162 - Warning: <img> lacks "alt" attribute
line 172 column 15 - Warning: <img> lacks "alt" attribute
line 389 column 11947 - Warning: <img> lacks "alt" attribute
line 397 column 22 - Warning: <img> lacks "alt" attribute
line 397 column 63 - Warning: <img> lacks "alt" attribute
line 397 column 112 - Warning: <img> lacks "alt" attribute
line 397 column 162 - Warning: <img> lacks "alt" attribute
line 398 column 11 - Warning: <img> lacks "alt" attribute
line 408 column 15 - Warning: <img> lacks "alt" attribute
line 417 column 651 - Warning: <img> lacks "alt" attribute
line 427 column 22 - Warning: <img> lacks "alt" attribute
line 427 column 63 - Warning: <img> lacks "alt" attribute
line 427 column 112 - Warning: <img> lacks "alt" attribute
line 427 column 162 - Warning: <img> lacks "alt" attribute
line 438 column 15 - Warning: <img> lacks "alt" attribute
line 459 column 1134 - Warning: <img> lacks "alt" attribute
line 467 column 23 - Warning: <img> lacks "alt" attribute
line 467 column 64 - Warning: <img> lacks "alt" attribute
line 467 column 113 - Warning: <img> lacks "alt" attribute
line 467 column 163 - Warning: <img> lacks "alt" attribute
line 468 column 11 - Warning: <img> lacks "alt" attribute
line 478 column 15 - Warning: <img> lacks "alt" attribute
line 485 column 268 - Warning: <img> lacks "alt" attribute
line 493 column 1373 - Warning: <img> lacks "alt" attribute
line 493 column 1469 - Warning: <img> lacks "alt" attribute
line 493 column 1574 - Warning: <img> lacks "alt" attribute
line 501 column 22 - Warning: <img> lacks "alt" attribute
line 501 column 63 - Warning: <img> lacks "alt" attribute
line 501 column 112 - Warning: <img> lacks "alt" attribute
line 501 column 162 - Warning: <img> lacks "alt" attribute
line 512 column 15 - Warning: <img> lacks "alt" attribute
line 529 column 22 - Warning: <img> lacks "alt" attribute
line 529 column 63 - Warning: <img> lacks "alt" attribute
line 529 column 112 - Warning: <img> lacks "alt" attribute
line 529 column 162 - Warning: <img> lacks "alt" attribute
line 530 column 11 - Warning: <img> lacks "alt" attribute
line 540 column 15 - Warning: <img> lacks "alt" attribute
line 562 column 44 - Warning: <img> proprietary attribute value "absmiddle"
line 562 column 142 - Warning: <img> proprietary attribute value "absmiddle"
line 562 column 245 - Warning: <img> proprietary attribute value "absmiddle"
line 571 column 25 - Warning: <img> lacks "alt" attribute
line 576 column 267 - Warning: <img> lacks "alt" attribute
line 149 column 50 - Warning: trimming empty <font>
line 556 column 17 - Warning: trimming empty <tr>
line 559 column 50 - Warning: trimming empty <font>
line 125 column 68 - Warning: <nobr> is not approved by W3C
line 141 column 68 - Warning: <nobr> is not approved by W3C
line 177 column 27 - Warning: <nobr> is not approved by W3C
line 413 column 27 - Warning: <nobr> is not approved by W3C
line 415 column 73 - Warning: <table> proprietary attribute "height"
line 443 column 27 - Warning: <nobr> is not approved by W3C
line 483 column 27 - Warning: <nobr> is not approved by W3C
line 517 column 27 - Warning: <nobr> is not approved by W3C
line 545 column 27 - Warning: <nobr> is not approved by W3C
Info: Document content looks like HTML5
Info: No system identifier in emitted doctype
Tidy found 129 warnings and 0 errors!


The alt attribute should be used to give a short description
of an image; longer descriptions should be given with the
longdesc attribute which takes a URL linked to the description.
These measures are needed for people using non-graphical browsers.

For further advice on how to make your pages accessible
see http://www.w3.org/WAI/GL.
You are recommended to use CSS to specify the font and
properties such as its size and color. This will reduce
the size of HTML files and make them easier to maintain
compared with using <FONT> elements.

You are recommended to use CSS to control line wrapping.
Use "white-space: nowrap" to inhibit wrapping in place
of inserting <NOBR>...</NOBR> into the markup.

About HTML Tidy: https://github.com/htacg/tidy-html5
Bug reports and comments: https://github.com/htacg/tidy-html5/issues
Official mailing list: https://lists.w3.org/Archives/Public/public-htacg/
Latest HTML specification: http://dev.w3.org/html5/spec-author-view/
Validate your HTML documents: http://validator.w3.org/nu/
Lobby your company to join the W3C: http://www.w3.org/Consortium

Do you speak a language other than English, or a different variant of
English? Consider helping us to localize HTML Tidy. For details please see
https://github.com/htacg/tidy-html5/blob/master/README/LOCALIZE.md