This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
KingofGamesYami's profile picture

Define custom characters

Started by KingofGamesYami, 26 August 2014 - 10:39 PM
KingofGamesYami #1
Posted 27 August 2014 - 12:39 AM
I originally brought this up here, however I think some have misinterpreted my suggestion. Here it is again.

1) People want smaller pixels
2) Bandwidth is messed up if we use small pixels
3) Thus, my suggestion: custom characters

Here's how it works: You give a function a 'character map' and a character (an undefined one, such as `). It sets the value of that character to the character map. It would not be able to redefine already defined characters, since that could create problems…

An example of how I would expect this to work(making an `):

local cMap = [[
10000
01000
00000
00000
00000
00000
00000
]]
textutils.setPixel( cMap, '`' )

There would not be more than two colors, because there are two colors: textcolor and backgroundcolor.

Now, to use this in an actual program:

local cMap = [[
10000
01000
00000
00000
00000
00000
00000
]]
textutils.setPixel( cMap, '`' )

term.write( "I can draw a `!" )

Edit: another idea, if it's called with only the string, it sets the first available character and returns it.


local myPixel = textutils.setPixel( cMap )
term.write( "I made ".. myPixel .."!" )
Edited on 27 August 2014 - 12:35 AM
Cranium #2
Posted 27 August 2014 - 01:00 AM
Well, as it stands now, we draw each character from the minecraft font, from assets/minecraft/fonts.
So I think to expand on your idea, you would have to define a character by first editing the minecraft font images, then creating a link to the new images, and call to them. So your idea of setting a character map would be fine, but it would have to be done in a different way. There would also have to be some way to ensure that the font is monospaced, otherwise you'll get extreme errors when setting these characters.
KingofGamesYami #3
Posted 27 August 2014 - 02:33 AM
Ok, so CC is now able to edit assets/minecraft/fonts somehow… That wouldn't cause any issues?

Wouldn't monospacing (or lack thereof) just cause the same issues as with an HD texture/resource pack font? Ideally you'd check the length/width of the string, and error if it doesn't fit.
Bomb Bloke #4
Posted 27 August 2014 - 03:01 AM
Presumably you wouldn't alter the actual fonts file (or even the copy MineCraft loads into RAM for proper use, for that matter). That'd alter signs and whatnot throughout the whole world, and changing fonts on one system would likewise change them for all.

Instead ComputerCraft would load and assign a version of the font array to every system and external monitor in the world (same as how they all get display buffers to track the characters currently on their screens) - that's what you'd end up editing. The logistics of distributing these fonts would be the only tricky bit that I can see, especially given that multiple MineCraft clients on the same server don't currently have to use the same fonts at all.

Spacing would be easy to enforce within the character allocation function. CC's font spacing bugs apparently only trigger if a custom font is active when MineCraft loads, so they "shouldn't" be a problem, though ideally they'd be fixed anyways.

Sort of going on a tangent, back in the day a lot of programs (especially games) worked by redefining the character maps of their host systems. I used to use the BASIC VDU command to do it on my BBC. Thing was, if a program didn't reset the character map when it was done you'd have problems…!
Edited on 27 August 2014 - 01:03 AM
Saldor010 #5
Posted 27 August 2014 - 03:26 AM
+1. I believe most of the problems that would have to be dealt with to implement this suggestion, would be worth it in the long run for such a huge advantage.
Cranium #6
Posted 27 August 2014 - 03:31 AM
Ok, so CC is now able to edit assets/minecraft/fonts somehow… That wouldn't cause any issues?

Wouldn't monospacing (or lack thereof) just cause the same issues as with an HD texture/resource pack font? Ideally you'd check the length/width of the string, and error if it doesn't fit.
Ah, no. I meant that you'd have do use a custom resource pack. Or patch Minecraft in a way that adds more characters to the fonts.
MKlegoman357 #7
Posted 27 August 2014 - 01:40 PM
Well, instead of having 'setPixel(string pixel, string character)' you could have 'setPixel(string pixel, number character)', in other words, instead of giving the function a string character to replace, you would give it an ASCII number of the character you want to assign that character to.

But the problem is, how to deal with clients having different fonts? Well, CC could just ignore what kind of HD or non-HD font the client has loaded and still create 6x9 (or 9x12, or whatever the default MC character size is) pixels.
Edited on 27 August 2014 - 11:40 AM
KingofGamesYami #8
Posted 27 August 2014 - 02:10 PM
Instead ComputerCraft would load and assign a version of the font array to every system and external monitor in the world (same as how they all get display buffers to track the characters currently on their screens) - that's what you'd end up editing. The logistics of distributing these fonts would be the only tricky bit that I can see, especially given that multiple MineCraft clients on the same server don't currently have to use the same fonts at all.
That is a good description of what I would expect to happen.

Well, instead of having 'setPixel(string pixel, string character)' you could have 'setPixel(string pixel, number character)', in other words, instead of giving the function a string character to replace, you would give it an ASCII number of the character you want to assign that character to.
No, actually I'd rather use the actual character. It'd be easier for people to understand, yet you can still get the ACII characters by using string.char( number ).
MKlegoman357 #9
Posted 27 August 2014 - 02:19 PM
With my change, you could still do something like this:


local cMap = [[
10000
01000
00000
00000
00000
00000
00000
]]
textutils.setPixel( cMap, string.byte('`') )

And would be able to do things like this:


...

textutils.setPixel( cMap, 159 )

And then use the character:


print("Custom characters! " .. string.char(159))

or

print("Custom characters! \159")

EDIT: for comparison, here's the usage of using characters and numbers as identifiers, respectively:

Char map:

--// 5x7 Char
charMap = [[
11111
10001
10101
10101
10101
10001
11111
]]

Strings as identifiers:

term.setPixel( charMap, '`' )

print("Special ` characters!")

Numbers as identifiers:

term.setPixel( charMap, 159 )

print("Special \159 characters!")
Edited on 27 August 2014 - 12:27 PM
electrodude512 #10
Posted 01 September 2014 - 02:54 AM
Or you could pass it a character and use string.byte if you wanted a number. It doesn't really matter, and if it gets done and you think it's done the wrong way you can make your own function that calls the real one with string.byte or string.char

function textutils.setPixelNum(charMap, num)
  return textutils.setPixelChar(charMap, string.char(num))
end
or

function textutils.setPixelChar(charMap, char)
  return textutils.setPixelNum(charMap, string.byte(char))
end


Custom characters should be per-computer (and per-monitor) but should only work on advanced computers. Global custom characters wouldn't make any sense at all. I think you should be able to redefine any character, even normal characters, but that there should be a function to reset all normally printable characters (or all characters, for that matter). In the case of texturepacks, they should be normally be ignored (i.e. assume the default one is in use), but there should probably be a function to get the name of the current texture pack. For HD texturepacks, there could be a function to get the resolution of the texturepack, which would influence the maximum resolution of a custom character. But HD texturepack support would probably overcomplicate everything.
MKlegoman357 #11
Posted 01 September 2014 - 12:06 PM
I don't think that the size of the character you are creating should depend on the currently loaded font, simply because different clients may have different loaded fonts. Also, the reason I think giving this function a character number and not a string is because in CC you cannot write any special symbols or letters from other languages (į;š;д;л) to the computer and to do that you would have to get to the actual file and edit it with an external editor, which is not suitable for servers. Also, if this system would be made correctly we would be able to assign numbers such as 1025 and 4566 to characters, which would be useful in a multitasking environment, where one program might set it's custom character to the "\" and another program might set a differently looking character for the same "/". Then, one of the programs could start to look weird.
Bomb Bloke #12
Posted 01 September 2014 - 12:49 PM
Whether the definition function should accept characters or numbers is a bit of a moot point, given that it'd be trivial to get it to accept either. Remember that there's a type() function which is ideal for dealing with that sort of thing.
MKlegoman357 #13
Posted 01 September 2014 - 08:18 PM
Bomb Bloke is actually right, this function should accept both, Lua is dynamically-typed language anyways, why not use this feature? One thing I see that, if this feature gets implemented, could cause more lag or anything is that redirects should be able to handle custom characters for a multitasking environment, so if people overwrite some characters in their program they would be reset back for another program. For example: I make a game in which I overwrite the character '>' and in that game, lets say I make it to look like '⚑'. Now, whenever I exit the game and head back to shell, it could then look something like this:


⚑ edit myGame

but the user didn't expect to see that, he/she expects to see the usual normal shell:


> edit myGame

That means, the term API should be recording what redirect target overwritten what characters and setting them back to what they were when redirecting to a different redirect target.

In addition to changing characters, I think we should also be able to reset them, and by that I mean resetting them back to the original ASCII character. For that, I think the new syntax of *.setChar/Pixel could be:


term.setPixel(string/number character [, string pixelMap])

#if called with two arguments, this function sets the character 'character' to the pixel map 'pixelMap'.
#if called with one argument, this function sets the character 'character' to the original ASCII pixel map of that character.
Edited on 01 September 2014 - 06:19 PM
Sebra #14
Posted 01 September 2014 - 09:09 PM
This would not work in multitasking environment, where you can switch between different font changing programs and even have them run in windows.
But why not to add such fun bugs? ;)/>
Saldor010 #15
Posted 01 September 2014 - 09:29 PM
Bomb Bloke is actually right, this function should accept both, Lua is dynamically-typed language anyways, why not use this feature? One thing I see that, if this feature gets implemented, could cause more lag or anything is that redirects should be able to handle custom characters for a multitasking environment, so if people overwrite some characters in their program they would be reset back for another program. For example: I make a game in which I overwrite the character '>' and in that game, lets say I make it to look like '⚑'. Now, whenever I exit the game and head back to shell, it could then look something like this:


⚑ edit myGame

but the user didn't expect to see that, he/she expects to see the usual normal shell:


> edit myGame

That means, the term API should be recording what redirect target overwritten what characters and setting them back to what they were when redirecting to a different redirect target.

In addition to changing characters, I think we should also be able to reset them, and by that I mean resetting them back to the original ASCII character. For that, I think the new syntax of *.setChar/Pixel could be:


term.setPixel(string/number character [, string pixelMap])

#if called with two arguments, this function sets the character 'character' to the pixel map 'pixelMap'.
#if called with one argument, this function sets the character 'character' to the original ASCII pixel map of that character.

term.PixelRestore( certain character, or left empty for all of them) ?
electrodude512 #16
Posted 02 September 2014 - 06:18 PM
This would not work in multitasking environment, where you can switch between different font changing programs and even have them run in windows.
But why not to add such fun bugs? ;)/>
Yes it would work. The window API would just have to add a virtualization layer to worry about it and translate custom character IDs. For non-overlapping windows, there might be a problem when there are more than a total of 256 characters.

And some people seemed they wanted these functions in textutils. They would have to go in term so they could be independent per terminal (and window).