Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.
Sign upTile mode needs refactoring #4236
Comments
This comment has been minimized.
This comment has been minimized.
JayThirtySeven
commented
Nov 9, 2013
|
One thought: A simple perl or python script could do a lot of the grunt work here; it'd be pretty easy to parse the JSON definitions for the objects, check the symbols and colors, then pick tiles and output the tileset. Not that your idea is a bad one; it would certainly make a lot of sense for the engine to support direct ascii-to-tile references. Just pointing out that an external script could accomplish the same task. I'm not familiar enough with the code to decide whether this feature should be added ^^. |
This comment has been minimized.
This comment has been minimized.
|
@JayThirtySeven True, but not ever tile modder can script, making the game more accessible to modders is important if we want to have mods/tiles. Otherwise they will be turned off by the complexity of it. |
This comment has been minimized.
This comment has been minimized.
JayThirtySeven
commented
Nov 9, 2013
|
@axujen Fair point; if you want all players to have access to this simpler tile binding feature, it probably needs to be built into the game. You could write a flexible script and document it well enough for non-programmers to use, but between writing the script, distributing it with the game, etc it would probably be just as hard as modifying the game directly. |
This comment has been minimized.
This comment has been minimized.
|
It could work if the output is inserted before the current work, as a sort of fallback, otherwise you wipe what's already there. In any case one would have to rework the image tileset anyway to add a new block, I'm not even sure if the size of the tile/number of cells is fixed or not. We should also determine how many ASCII+colors variations the game is currently using. There are only 16 colors, to multiply for the number of ASCII being used. It's still lots of space. And when you are at it, it would be better to use two image files. One with this combination of ASCII + colors, the other with the tiles. |
This comment has been minimized.
This comment has been minimized.
JayThirtySeven
commented
Nov 9, 2013
|
@Abalieno a quick analysis of the cataclysm/data/json/ folder (and subfolders) shows 439 unique combinations of symbol+color, while there are 1520 possible combinations if you have 16 colors and 95 symbols (wikipedia says there are 95 printable ASCII chars, dunno if cataclysm has any extras). My script was fairly simple and counted a couple of weird symbol entries like "LINE_OXOX"; I don't know what those are used for so I'm not sure if they should have been counted. In any case, I think the important conclusion is that there are more than 400 combinations in use, but there could be more than 1000 in theory. |
This comment has been minimized.
This comment has been minimized.
|
Well, in any case it would be faster to have a standard ASCII block, and then you run colors on it (so you just paste it over and swap colors). Like make the 95 symbols block, then repeat 16 times for every color. And then auto-bind it in the json with some tool. I just don't know if this can be appended to the current image tileset. |
This comment has been minimized.
This comment has been minimized.
|
Some more details on how this should work best: We need three fallback mechanics. First the game looks for the specific ID (as it does now), using the current order of priority, so that if something is defined twice, only the most recent definition is valid. If then the ID does not exist the game looks for its "category". And if the category also doesn't exist it looks for the ASCII+color combination associated with that object, and uses it. Only if this ALSO fails it should fallback to "unknown". So it goes from highest to lowest priority: ID -> Category -> ASCII+color -> unknown In my case I don't really need Category since I think ASCII+color is ideal, but maybe other tilemakers prefer using categories. And in the case someone actually works on this it would be ideal to split the actual tile source images in two (or even three): the IDs source image, and the ASCII+color source image. |
This comment has been minimized.
This comment has been minimized.
JayThirtySeven
commented
Nov 10, 2013
|
In my opinion it would be even more ideal to allow an arbitrary number of source image files; it feels like an arbitrary restriction to tell the tileset designer how many files he should use and what they should be named. The engine could pretty easily combine tiles from any number of files into one master surface. A rough memory estimate: ten thousand 16x16 tiles on a 32bit surface comes to about 10mb. My reasoning: The engine doesn't mind reading tiles from one giant image file, but with a little extra code can read tiles from a series of image files. The human tileset designer, on the other hand, might have a much easier time if he can organize his tiles into several files instead of trying to work on a single giant image. That said, we're still talking about "ideal" here. Right now the code reads one file and the primary issue is enabling fallback tiles. Reading three or more files can wait. (Final thought: A separate file with greyscale tiles in ASCII order could be a good way to handle the final ASCII/color fallback situation.) |
This comment has been minimized.
This comment has been minimized.
Those are walls. |
This comment has been minimized.
This comment has been minimized.
|
I think the problem here is twofold. Some publicly accessible script is absolutely a requirement, but some fallback that can adequately handle new items that are added is also required. If the fallback logic accepts an image-per-symbol plus a pallet per color, that would be a lot more effective and versatile than having to individually tile every possible symbol/color. |
This comment has been minimized.
This comment has been minimized.
|
basically, the tile artist would create a "pallete" for every available color (so sixteen pallets) and then an image for every symbol (a bit under a hundred, but eh) but those images, and that's a lot less than the 1600 pairs you would need to make otherwise, and would easily allow us to set up a base default for future tilesets to fall back to. |
This comment has been minimized.
This comment has been minimized.
|
It's the same for me, but I guess more complex to code. It takes really nothing to cut&paste a block of text 16 times and then change the color for each bock. |
This comment has been minimized.
This comment has been minimized.
JayThirtySeven
commented
Nov 17, 2013
|
It also wouldn't be too hard to have just one set of 95 tiles for all ascii symbols in white/grayscale, and then have the game automatically generate the other 15 color variations. |
This comment has been minimized.
This comment has been minimized.
|
Yeah instead of the artist supplying a pallete he could just supply a color hex code in tileset.json, if we're already coloring tiles dynamically it shouldnt make much of a difference |
GlyphGryph
referenced this issue
Nov 17, 2013
Closed
Possible plan for tileset fallback handling #4448
This comment has been minimized.
This comment has been minimized.
|
All is idle on the coding side? Because working on the tiles now it's kind of useless. Whenever (if ever) this feature is added I'd have to REMOVE a whole lot of stuff, because not needed anymore. So any work I could do on my tileset is completely pointless the day this feature is added. |
This comment has been minimized.
This comment has been minimized.
|
The ASCII replace is good for items that would work with all of the same images, but guns for example are more fun to create multiple images for and in the code both. The BB gun, the sling, the pipe .45 SMG, sawn-off shotgun, double barrel shotgun, ppsh, marlin 9a, ruger 1022, remington 700, m14a, ... and many others are all a brown ( For a more symbol-based set like yours it would work, but Deon's, Tsu's and Hoder's all have different graphics for these things. |
This comment has been minimized.
This comment has been minimized.
|
"The ASCII replace is good for items that would work with all of the same images, but guns for example are more fun to create multiple images for and in the code both." "The ASCII replace" is a fallback mechanic. It means that first it looks if an individual ID/tile exists, if it DOESN'T then it goes to ASCII fallback. You can still tile every individual IDs if you so choose. This removes absolutely nothing from the current style. We need to stop arguing about this. There's nothing that still needs to be figured out or planned. It just needs to be implemented. And since it doesn't require any fancy new technology or strategy it simply needs a coder who is able to move and rearrange parts of the code already there to make it do the things it should do. If we know how to open and index one .png then we know how to open and index two of them. Once you have the index and you know for example that the ASCII "*" and color "blue" correspond to tile # 1234 in my .png then you know which tile needs to be drawn on screen. It's TRIVIAL, but it needs code, not words. |
This comment has been minimized.
This comment has been minimized.
|
Pseudocode to be more clear: "BLACK" : 0 These are constants ideally representing the 16 colors that the terminal can use. In our case they are offsets. Now let's say that we need to print on screen a "kevlar vest". The kevlar vest ID is "kevlar", so we look into tile_config.json if "kevlar" is defined. It isn't. In the current code it means that an "unknown" tile is going to be printed. Instead in the new code we look at the ASCII fallback. The "kevlar vest" is represented by a "[" colored "light_gray". I suppose that light gray in my list of constants is "GRAY", so a "7". Let's say that in the default ASCII sequence the character "[" is in the 80th position when the first cell is 0. This means that if I wanted a black (0) "[" I would need the 80th tile in the .png. But I want the gray one. Say that we use 100 individual ASCII. So from 0 to 99, you have all black ASCII. From 100 to 199 all red ASCII and so on. This means that a gray "[" is tile number 780. Print tile number 780. Done. .png example: http://cesspit.net/misc/source.png Why can't this be done, and why should we continue arguing (on the forums and here) about something THIS simple? |
This comment has been minimized.
This comment has been minimized.
JayThirtySeven
commented
Nov 23, 2013
|
I'm willing to give it a shot if nobody else is working on it right now. It'll be my first contribution to this code base, but I've done these sorts of tile loading/lookup system before. I guess I'll fork and start looking into it; if anybody want to stop me please do so ASAP so I don't waste too much of my time. |
This comment has been minimized.
This comment has been minimized.
JayThirtySeven
commented
Nov 23, 2013
|
Okay, nevermind, the tile code is way hairier than I was expecting. I may still help with this, but just trying to understand the existing code will take too long for me to start soon. |
This comment has been minimized.
This comment has been minimized.
|
I agree this is a mode we should support, and it is just one level of |
This comment has been minimized.
This comment has been minimized.
|
I wasted two days trying to do this myself, but nothing. As explained in my forum thread: the big problem here is that the tile code works on a completely different level than curse. This means that tile functions don't have even the vague idea of what a "color" or a "symbol" is. The tile functions know a bed is a string ID "bed", and then it looks up to the tile number associated. THERE'S NO FUCKING WAY to recognize the bed as a '#' standard. We have the IDs of objects, but nothing else. So we don't know anything that is associated with that IDs in the data json. There's obviously no way for each frame and each single tile to search through all the data files and find a specific ID. It's insane. So the only way I could think to do this, would be about initializing a kind of library object specific for ASCII fallback and to store along with the tile object. So we go through ALL the data json, and store every ID with matching color and symbol. At that point you actually can have a simple lookup by using that library object. But that means writing a json parser that builds the object and a lookup function. All stuff beyond my level. And probably beyond the interest level of those who could do it. |
This comment has been minimized.
This comment has been minimized.
|
In There is also a In |
This comment has been minimized.
This comment has been minimized.
|
Yes, but it needs to work with ALL IDs. Everything possible. So not just "furniture", but also terrain, monsters, items and so on. If it's simple for you could you write down an example that would cover all cases and fit in the cata_tiles::draw_from_id_string function? |
This comment has been minimized.
This comment has been minimized.
|
Really quick and really dirty: 852ce54f3683696a3b3ef5f657038f036ae7f9a7 There are "some" visual glitches because the "text" (it's only a single character) that gets displayed is only half the width of the tiles. And it's not centered. Btw. which forum thread? I must have overlooked it. There are still some things missing: bullets, cursor, lighting, player/npc symbol, explosion, animation hit, footstep, weather, animation line |
This comment has been minimized.
This comment has been minimized.
|
That was really helpful. We were trying to work this out in the chat. The problem I have now is that even after getting symbol+color we have the problem of objects that use not just a foreground color, but also a background one. So my png just wouldn't work since it cycles only foreground colors. I guess the ideal is to be able to use a function that takes a white png and is able to recolor both foreground and background. But again way beyond my skills. You example instead maybe uses some external fallback? OutputChar(sym, screen_x, screen_y, 1); So it bypasses the normal tile drawing? It can work, but it means it isn't using the tileset, I guess. So it's all the wrong size. About the things missing: it doesn't matter. Those few cases are easily covered by the tileset already. We only need support for the discrete objects. Like items, monsters and whatnot. It's all already fine. We just need a way to use the png tileset and maybe recolor it properly. |
This comment has been minimized.
This comment has been minimized.
|
Well, it's something: Basically what's missing is drawn with the standard font used for the UI. But that obviously screws up the tile sizes. So we need an output function that actually does use the tileset itself. And ideally have it being able to recolor with the right colors. |
This comment has been minimized.
This comment has been minimized.
As far as I know a background color in ASCII is used when there's more than one object in that tile. In tile mode we have an overlay. So if stuff is drawn in a black background it's fine. In any case this will have to do until someone figures out how to recolor the tile on the fly (so it will never happen). |
This comment has been minimized.
This comment has been minimized.
|
Some critters (Jabberwock, exotic zeds) and furniture (sofas, etc) are drawn with non-black background colors. Sorry to inject more complexity. :-/ |
This comment has been minimized.
This comment has been minimized.
|
I know, but we can't do much about it. New progress: If the colors are slightly weird it's because I'm using my personal palette. I also have my own colors.json raw. So we get a decent ascii fallback and right colors. Multi-tile things like walls are displayed wrongly, but we do not care about those, since that stuff should always be handled within the tileset, without ASCII fallback. There's a REALLY strange issue, tho. When there are "holes" in the map it looks a bit like Doom's Hall of Mirrors effect. But the weird thing is that under the tilemap you can see chunks on the map drawn with the UI font. I'm wondering if the game actually draws first the map in normal curse mode and then draws the tilemap RIGHT ON TOP. Because I really can't explain how it's possible that when there are undefined tiles the game displays the other map under it. It shouldn't happen, it should just display nothing. Anyway, to get the color right this is the code:
So once again, whenever there's no defined ID we look into symbol + color. If those are defined, I set "fuck" to true. So that fuck = ascii fallback active. Then, just before calling "draw_tile_at", I have that piece of code that passes the correct values to display_title. I probably should add a check so that sym stays within certain boundaries, because I guess that's what causes the "holes" into the map, when things like walls return weird values. |
This comment has been minimized.
This comment has been minimized.
|
Speaking of which: If the terrain is not drawn (because it's fg and bg are both invalid), and there is nothing else on that square that gets draw, than nothing will be drawn there at all. And SDL does not erase the screen each frame, which means area that is not overdrawn will stay unchanged. If the square is invisible (out of range, dark) the code in But if the square is visible, the terrain is supposed to overdraw it with the current terrain. If that does not happen (because of the mentioned invalid fg&bg values), it stays unchanged. This should be visible when moving around. |
This comment has been minimized.
This comment has been minimized.
|
Got a problem. Those things that got double colors are drawn as "transparent". So how do modify this: So that I can check if a value is out of range and so return only the first color? |
This comment has been minimized.
This comment has been minimized.
|
Wow, you guys are making excellent progress. |
This comment has been minimized.
This comment has been minimized.
|
I think you shouldn't use
By "double colors" you mean foreground == background?
|
This comment has been minimized.
This comment has been minimized.
|
I've fixed the warped Hall of Mirrors effect. Code-wise it's still sorta broken, but I've figured out it depends on the "lighting_hidden" tile. If this is undefined you get all sort of graphical corruption. If it's defined then everything's fine. Other bugs:
The code right now is:
These two: What I need help with:
|
This comment has been minimized.
This comment has been minimized.
Yes. color_to_int returns 143 values. I can only display 16. Since I cannot fucking find any sense in how the others are distributed, I couldn't find a logic that would simply strip the background color. So I simply made a modulus color % 16, just to make sure the color is in range. But it would be better if at least we default to foreground color, instead of a conversion at random. What should have the priority is the sub-tiles like walls. Right now ASCII fallback DOES NOT display what ASCII would. Car parts are all like jjnnkk where instead there should be lines. |
This comment has been minimized.
This comment has been minimized.
To be able to know in what sequence I need to build my ASCII tileset. I tried your code with colorpairs. That's when yellow was both 3 and 7, if you look upthread. Since I couldn't find any logic on how color values are returned, I simply went to color_to_int, whose output is at least PREDICTABLE. And I'm not building my tile again to rejuggle the color sequence. Right now it follows the order in color_to_int. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
That's the best I can explain it: #4236 (comment) c_yellow is not a color. It's a index of a color pair: a pair of foreground and a background colors. COLOR_YELLOW is a color. It can be used as foreground or as background. |
This comment has been minimized.
This comment has been minimized.
|
@BevapDin I understand the point. But I can't write better code than that. So I can't handle color pairs and I simply used what I could handle. Whoever wants to write better code is welcome. About the poppy flowers: nevermind. They aren't poppy flowers. They are rocks. Rocks in the last experimentals are BROKEN. So it's not my code. Do I have to open another issue for the broken rocks or it is known? |
This comment has been minimized.
This comment has been minimized.
|
After porting the code to the last experimental lots of objects aren't shown at all. Since the code it's the same it may be related to the rock bug. So I don't know if there's something wrong in the code, or if it's about bugs in the experimental. Everything looks fine using @BevapDin branch. |
This comment has been minimized.
This comment has been minimized.
|
More bugs:
|
This comment has been minimized.
This comment has been minimized.
|
See here for my changes: https://github.com/BevapDin/Cataclysm-DDA/tree/tile-mod-2 The tileset image is faulty: the last line of the magenta block is missing. Therefor all symbols behind that are shifted. That's why the windows are displayed as '7'. Other than that it looks good. |
This comment has been minimized.
This comment has been minimized.
|
I'm using different sources now: EDIT: this one is based on latest experimental and includes your display object fix: |
This comment has been minimized.
This comment has been minimized.
|
The tileset file is still broken (missing line for magenta, third block from bottom): For same reason this is fine (has 16 lines of magenta chars): |
This comment has been minimized.
This comment has been minimized.
|
Because I always make a mess of backup and copies and whatnot. The one that is being used retrodaystiles.png is correct. (so the rest is just garbage that doesn't affect the game itself) |
This comment has been minimized.
This comment has been minimized.
|
Btw, could you fix my code there with the way colors are handled? There were also issues displaying traps, caltrops and finally the thing with multi-tiles. But look up my code since I'm using different functions from yours. |
This comment has been minimized.
This comment has been minimized.
|
Ups, I was wrong again. retrodaystiles.png is not fine. Magenta is fine, but he last line of the last color is missing instead. About your code (would be easier if I could use git to compare it): traps: you didn't include the code that handles trap ids:
Still using
multi-tiles: yes, that is difficult. I think the best would be to create the symbol in draw_terrain and pass it to draw_from_id. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Uhm, for some reason "caltrops" don't display correctly even if traps are fixed now. That's the only thing bugged as far as I know. Anyway, I've reached the end of what I can do. Now it's up to you if you want better code. I'm happy with what I have even if it's not perfect. Things one might look into:
Then tile mode still has its own problems compared to ASCII. It needs a better light system, for example. And I think it misses some effects, like the red square when you attack something. |
This comment has been minimized.
This comment has been minimized.
|
One problem I encountered is that newer tilesets such as Coleen's don't fallback to ascii, but instead a default tile. This is the entire reason why I'm still using RetroDays. Any idea when this will be fixed |
This comment has been minimized.
This comment has been minimized.
|
Probably when someone sets those tilesets up to take advantage of the fallback code, and/or points the fallback code at those tilesets, and PRs the fix? KA101, like the rest of the core devs, uses ASCII so doesn't pay much attention to tiles |
This comment has been minimized.
This comment has been minimized.
|
By PR I assume you mean pull request? |
This comment has been minimized.
This comment has been minimized.
|
Correct. |
This comment has been minimized.
This comment has been minimized.
This issue was closed as it appears inactive.Reducing open issues to those which are (or will) be actively worked upon helps us focus our efforts. This issue has not been deleted - it still appears in searches and if it contains relevant information you are encouraged to continue to link to it. If this issue was a bugIt should be reopened if it can be reproduced in the current build. You can obtain the most recent copy here. Please check there is not a more recent report of this bug before doing so. If no more recent report exists you should continue the discussion in this issue. If this was a feature requestIf the consensus was that the idea was good you could consider submitting an implementation via a PR. If you want to comment further please do so here as opposed to opening a new issue. Before posting check nobody has already made the same point and consider whether your comments are likely to lead to an implementation. If you have doubts about either consider instead voting for the issue If you want to work on this issueThen either assign it to yourself or if you are unable to do so claim it via adding a comment. Please don't assign others or make a general request for action. |

Abalieno commentedNov 9, 2013
I explained this on the forums. Right now it's just not possible to complete a tileset and maintain it. You just need a million of hours and every time stuff is added you have to go through a lot of busywork.
Here's the suggested refactoring to make this work:
I just spent a VERY long time going through all "books.json" to add ALL entries to the tileset. It's insane work.
This is something that needs to be refactored and that is more important than categories: we need a way to bind tiles NOT through IDs, but through ASCII+color.
It's just not remotely possible to bind every single ID for the billion of objects in the game. The real problem here is that there are like 50 books that have different IDs but that are all shown as a pink "?". So I don't want to use 50 entries IDs in my tiles file pointing to the same tile. I just want to bind the pink "?" ASCII to a tile. Once. All objects that are shown as a pink "?" will then default to that tile.
So, basically, we should build tiles for all used ASCII+color combinations. There should be an automatic method/output file that lists every combination and what it is associated to. Something like the green "/" represents this list of objects. And then let tile-makers bind one tile to the green "/", and not IDs (unless overridden with a specific ID).
So the "tile_config.json" should first have a mandatory block where you bind all ASCII and colors in use (surely a MUCH SMALLER number than all the IDs in the game). THEN an optional block where you bind single IDs, if you want.
That way every time you add stuff to the game, you ALWAYS have tile mode working perfect, because it always knows how to output that ASCII+color combination by default.
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.