Giter Site home page Giter Site logo

jujuadams / scribble Goto Github PK

View Code? Open in Web Editor NEW
317.0 15.0 43.0 28.02 MB

Efficient, internationalized, multi-effects text renderer for GameMaker

Home Page: https://www.jujuadams.com/Scribble/

License: MIT License

Game Maker Language 96.20% GLSL 3.80%
gms2 gamemaker text dialogue gamemaker-studio-2 l10n i18n localization internationalization

scribble's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scribble's Issues

Remove SCRIBBLE_Z from macros?

SCRIBBLE_Z currently passes in a uniform into the default Scribble shader to control the eventual vertex z-position of text. We do this because Scribble hijacks the z-coordinate of the vertex position to communicate other data (specifically the character/line index).

Passing around SCRIBBLE_Z as a uniform has a non-zero cost for rendering text and it adds clutter to the library in general. I feel like if someone was using GM for 3D they'd understand enough about shaders (the graphics pipeline in general) to make this edit themselves.

Scribble equivalent of string_width and string_height

I'm curious if there's a way to get the width and height of a string that would be drawn using scribble_draw. Something like the build in string_width and string_height functions, but using the scribble draw state.

Is there a way to do this? If not, consider this to be a possible feature request :)

Blacklist/Whitelist sprite command tags

When storing text externally, Scribble is potentially exposing all of its sprites for use. This is a mild security hole as it allows sprite names/images to be accessed by changing said external files.

Sprite origins

At this point I'm not sure if there's something wrong or if I'm just breaking everything I touch. Empty project, sprite alignment is "middle center," the alignment is set to scribble_draw_set_box_align(fa_center, fa_middle) and the yyz is attached.

If I had to take a guess this is a similar issue to #10 and #16 .

image

internal-screaming.zip

game_restart() throws an error

Scribble actively prevents the user from reinitialising the library as this causes a ton of issues. This causes issues when someone wants to use game_restart(), however.

...not sure why people are using game_restart() but here we are.

SCRIBBLE_WARNING_REINITIALIZE should be added as a macro to control whether a warning is shown when trying to reinitialize Scribble. Additionally, scribble_init() should return whether the library was initialized successfully. This allows the following design pattern:

if (scribble_init(...))
{
    //Initialized for the first time, define things that we need
    scribble_add_spritefont(...);
    scribble_add_font(...);
    scribble_add_color(...);
    scribble_autotype_add_event(...);
}

Add a function to define a font using a custom sprite+JSON

Sometimes it's useful to add a font from a sprite (but not a spritefont!), for example for a testing program that allows the user to add fonts defined in their own project.

In the future, this feature can be used to handle SDF fonts.

Add text preview tool

A text preview tool would be useful to test features during development, to act as a demo, and to allow for quicker production of text. It may also be useful for localisation work.

Runtime 2.2.2.326+ breaks sprite fonts yet again

Looks like the newest runtime, 2.2.2.326 breaks sprite fonts again, like in #3.
Fortunately, it seems like it's only the padding around the font changed.
https://github.com/GameMakerDiscord/scribble/blob/60151c89a756edc942b76a24869c88e91adffc40/scripts/scribble_init_end/scribble_init_end.gml#L150-L151
Changing the 3 to a 1 in here seems to do the trick.
It may have something to do with my texture group options (Border size: 2; Automatically crop on), but changing these does not seem to influence the generated cache files at all (at least not in a positive way - the automatic crop causes the letters to be tiny instead of too big).

I have SCRIBBLE_EMULATE_LEGACY_SPRITEFONT_SPACING turned off, too. Turning it on just causes the spacing between the letters to be 2 pixels too short.

Running scribble v4.4.1, Windows 10 1809.

Using autotype sound effects calls random() functions

For procedurally generated games or for games using lockstep networking, the use of randomising functions needs to be very carefully controlled. Autotype uses GM's native randomisation functions to select sound effect and pitch and this may cause unexpected issues with certain kinds of games.

These will need to be replaced with a custom internal random function. The quality of the randomisation function is particularly important so a LCG (e.g. Lehmer) will do just fine.

Add example for typewriter delay and pause

One of the most common requests for the typewriter is to include a [delay] and/or [pause] command. This ends up being quite complex to implement in a general way. It's possible to use the event system to this yourself, but that's quite complicated for new users.

The solution is just to add an example for delay/pause commands built with the events system. This could also include a tutorial on the wiki.

Add pages

Scribble currently supports horizontally wrapping text but doesn't support limiting the vertical height of a textbox. It's possible to simply cut off the bottom of a textbox but that's an inelegant way to solve the problem. Adding pages to Scribble means it's possible to chuck any length of text at the system and it'll find an appropriate way to show that to the player.

Once a line of text exceeds the vertical limit of the textbox, Scribble will create a new page and begin writing text to that new page. Functions will exist to switch pages. Switching a page will reset the autotype state.

Add support for sound pitches

As it stands now, with the new sound feature, we can provide an array of sounds from which scribble will pick one. I think another feature where you could also provide a pitch range for the played sound would be great.
Something like audio_sound_pitch(sound_index, random_range(range_lower, range_upper)) should be pretty simple and could be incorporated great into scribble_autotype_set_sound, e.g. scribble_autotype_set_sound(element, sound_array, overlap, pitch_array) or even scribble_autotype_set_sound(element, sound_array, overlap, pitch_lower, pitch_upper). Or maybe even a pitch_offset which would generate a range +- the offset, e.g. [0.8, 1.2] from offset 0.2.

I can provide a PR in the following days if you are too busy to implement that. Thanks!

Improve documentation

Documentation for Scribble currently mostly lives in script headers. This isn't convenient for most people and limits what formatting can be used. Better documentation makes the engine easier to use and, hopefully, will reveal ways that the API can be streamlined further.

Effects exaggerated with small fonts

Not sure if this is a bug or not.
But when using effects, it seems they are very exaggerated with small font sizes:

example
It's especially obvious with [shake]
This font is 12x9 pixels per character.

It might be nice if there's a simple way to tweak those settings, unless I'm just missing it.
Thanks!

Occasionally spritefonts will be rendered with some characters garbled

Spritefonts are rendered under the assumption that all characters lie on the same texture page. Due to GameMaker's texture packing behaviour, sometimes individual images of the source sprite might lie on another texture page. At this time, it is not clear if GameMaker gives us sufficient tools to detect and mitigate this problem.

Observed:
Observed

The current workaround is to put the spritefont in its own texture group and I've updated the wiki accordingly.

Autotype position off when pausing

Hey, it's me again, with a problem similar to #11, in fact, it may be the very same problem, but in v5.0.X.

I tried forking scribble and adding a clean way to "interrupt" the autotyper by adding a new property, but there is a consistent issue that the "pausing" happens one character too late.
I'm not sure, but it could very well be that the event triggers one character later, since the script call happens in the middle of the autotype processing and is directly referencing it. I don't think it's a shader issue this time. I tried looking for rounding errors, too, but I don't think that's it either.

Regardless, I'm not confident enough to just put a -=1 somewhere in there, so I was hoping you could check out the patch here:
glitchroy@815d129#diff-ea72a6c3e7f97ed30382838bacf15089
It's not about accepting the feature in the first place, since I did add this behaviour without forking scribble previously (and because it didn't work, I started taking a "cleaner" approach). This is just a convient way to see the problem, I think.

Thanks!

Allow the definition of a fallback character

When dealing with usernames, it's usually not possible to constrain what Unicode characters are going to be given to your game. Many target platforms expect that you replace any missing characters with “□” (U+25A1).

GameMaker doesn't natively support this, but Scribble can!

Add fixed line height optimisation

Whilst it's convenient to be able to dynamically resize lines of text depending on their contents, more often than not a fixed line height is adequate. By fixing the line height, some optimisations can be made.

Typewriter position off by one

Hey,
maybe this problem only affects me, but after updating from scribble v4.5.1 to v4.7.3, the typewriter seemed to be shifted to the right by one character.
More specifically, I implement a [pause] custom event which halts the typewriter by setting json[| __SCRIBBLE.TW_SPEED] to 0 temporarily (ugly, I know). After the update, even though __SCRIBBLE.TW_POSITION seemed unaffected, the pause happened one character too late.
After multiple days, I tracked the change down to the shader, specifically this line:
https://github.com/JujuAdams/scribble/blob/ca1a6d1523171883f9c19b72dfbaf577ab8e32c1/shaders/shScribble/shScribble.vsh#L141

Changing the param argument to (in_Normal.x+1.0)/u_fCharFadeCount seems to fix my issue. Since I'm not really a shader expert and in_Normal is some kind of default parameter, I can't really trace the root cause back. Maybe someone knows what's causing this behaviour? I compared scribble_step() and other scripts between the versions, but I do think it's because of the shader and the corresponding call from scribble_draw().

Thanks!

PS: I'm only using the "per character" draw setting for the typewriter, so I'm not sure how this would affect drawing by line.

Request: replacement for string_length()

A way to get the length (numb of characters) of a scribble string without the commands would be nice.

I was hoping to just write a script that would grab _scribble_array[__SCRIBBLE.CHARACTERS] (or some other part of the scribble element array), but __SCRIBBLE.CHARACTERS doesn't include spaces in its count.

I can achieve what I'm needing with this estimate, but an exact string length without manually parsing would be nice.

Add outline functionality

Outlining text is a common operation for both pixel art and hires fonts. Scribble should support this.

There are many ways to achieve the effect including:

  1. Layered draw calls (in our case, layered quads)
  2. Pre-outlining a spritefont
  3. Caching text onto a surface and layering the draw call
  4. Signed-distance field font
  5. Edge detection shader

Add support for kerning pairs

Kerning pairs are often used in fonts (mostly non-spritefonts) to improve the look of certain letter pairs e.g. A+W = AW

This is not to be confused with a ligatures e.g. f+i= fi!

GM creates kerning pair data but Scribble does not currently respect that data (and neither does the native draw_text as far as I know). It should be relatively easy to handle kerning pairs given the data is available, but I am concerned about backwards compatibility within Scribble, and performance due to additional ds_map hits.

Additionally, functions should exist to edit kerning pairs and to create new ones. This will be especially useful for spritefonts.

scribble_draw_set_wrap() doesn't warn people when updating from before v5.4.3

scribble_draw_set_wrap() changed its argument order in v5.4.3, but no allowance is made for automatically checking to see if the old argument order is being used in a project.

We can scan for a value of 0 or 1 being sent in for the (optional) maxLineHeight argument and report this as an error. It's unlikely that a line height of 0 or 1 would be used in reality so this is a fair way of checking for this mistake.

drawing sprites while using a spritefont draws them in a weird location

Using sprites in the middle of a scribble string is great.
but if using a spritefont, it seems to draw the image down really far.
example:

scribble_draw_set_box_align(fa_left,fa_middle)
scribble_draw(20,400,
"\n[][sfont][sprite_fire,0,.1][scale,3] this is [c_red][wobble]fire..."+
"\n[][sprite_fire,0,.1][scale,3] this is [c_red][wobble]fire...");

looks like this:
image

The top is using a spritefont, and the bottom a normal font.
Font alignment or sprite origin doesn't seem to make any difference, but scaling the font seems to make things worse. Here, the spritefont isn't scaled up:

image

Document shaders more

Version 6 will include a reworking of how shaders are exposed on the GML side. This requires documentation, which is good because shader documentation for Scribble has historically been poor.

Limited functionality in HTML5

It would seem the only way to get scribble working on an HTML5 build is to use a sprite font. Might be a problem with the way HTML5 building handles included files and sprites. I am not sure thought. Glyph usages is broken too, but [c_color], [wave] and [rainbow] work.

Errors yielded are not very useful from my perspective, even from Debug mode:

Attempting to use sprPlayer sprite as a glyph

Error: must be an array
--------------------------------------------------------------------
	function _Uf("must be an array")
	function __yy_gml_array_check_index(0, [undefined])
	function gml_Script_scribble_draw([instance], [instance], 120, 120, "[sprPlayer]")
	function gml_Object_oGame_Draw_64([instance], [instance])
	function(2112, 0, [instance], [instance])
	function(2112, 0, [instance], [instance])
	function([unknown], 2112)
	function([unknown])
	function()
	function _q13()
	function _V03()
	function _A03(4919.792)

Add tag that allows for dynamic recolouring of glyphs/sprites

In some cases, a developer might want to recolour certain portions of a text element without regenerating the whole text element. Whilst this is possible to program in manually, Scribble could support this natively.

Given issue #14 and the impending changes with GMS2.3.0, now might be the time to spruce up the shader effects system.

Runtime 2.2.1.287+ breaks font loading for sprite fonts

The changelog for runtime 2.2.1.287 states:

  • Asset Compiler
    • Sped up constructing texture pages from texture groups
    • Handling of cropped textures has been improved

(source)

This breaks the glyph data scanning in scribble_load_fonts() (at line 126 and following). Looking at the generated cache files, it seems that the TexturePageEntries for the font sprites now all generate with a 1px transparent border around them, regardless of texture page settings.
This causes the fonts to look jagged and cut off, probably because the sprite file is bigger than expected.

Downgrading to runtime 2.2.0.261 fixes the issue for now.

Surface optimisations for static portions of text

Taking cues from other text renderers, Scribble could use surfaces to cache static portions of text so that the number (and complexity) of vertex buffers can be reduced.

I'm not sure what this would mean for the typewriter effect. Perhaps we could limit surface caching to either 1) non-typewriter text 2) text with a fixed line height. Having a fixed line height means we can write a shader that reveals text on the surface via a fragment shader.

Description for SCRIBBLE_HASH_NEWLINE causes parsing issues

The newline-character in the comment of the SCRIBBLE_NEW_HASHLINE macro (__scribble_config(), line 8) causes issues with parsing the next macro in line correctly.

Error log:


___________________________________________
############################################################################################
FATAL ERROR in
action number 1
of Create Event
for object oInit:

Variable oInit.SCRIBBLE_COMPATIBILITY_MODE(100015, -2147483648) not set before reading it.
 at gml_Script_scribble_load_fonts (line 146) -         if ( SCRIBBLE_COMPATIBILITY_MODE ) global.__scribble_sprite_font_map[? _name ] = font_add_sprite_ext( _sprite, _sprite_string, true, _shift_constant );
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Script_scribble_load_fonts (line 146)
called from - gml_Script_scribble_init_end (line 13) - scribble_load_fonts( global.__scribble_init_font_array );
called from - gml_Object_oInit_Create_0 (line 6) - scribble_init_end();

As you can see, the next macro in line is not created correctly.

What doesn't work:
Escaping the newline character, e.g. (//Replaces hashes (#) with newlines (\\n) to emulate GMS1 behaviour).

What does work: Removing the \n.

Why a comment is parsed at all in this way is beyond me.
Tested on scribble v02.03.00, GMS2 v2.2.1.375, GMS2 Runtime v2.2.1.291, Windows 10 1803.

Pre-caching and setting autotype in the same frame causes timers to never be incremented

Here's a fun problem that I've tracked down the cause of, but don't know what a solution would be.

I like to pre-cache my scribbles when possible, to ensure that everything I pass to scribble_draw is a scribble array because that makes things easier when dealing with autotype.

var _stext = scribble_pre_cache_ui("the quick brown fox jumped over the lazy game dev");

All that script really does is set and unset the cache group, it's not that interesting.

scribble_draw_set_cache_group(ScribbleCacheGroups.UI, false, true);
scribble_draw_set_wrap(-1, width);
var scribble = scribble_draw(0, 0, text);
scribble_draw_set_cache_group(ScribbleCacheGroups.UI, true, true);
return scribble;

Anyway, I like to do this often, especially in menus and stuff.

var _stext = scribble_pre_cache_ui("the quick brown fox jumped over the lazy game dev");
if (scribble_text == undefined) {
    scribble_text = _stext;
    scribble_autotype_fade_in(scribble_text, ...);
}
scribble_draw(a, b, scribble_text);

This used to be fine, but at some point it stopped working. I'm not sure when exactly that happened, since I only noticed last night after revisiting some old code. Every time scribble_draw is called - regardless of whether the scribble is actually drawn, or anything - the scribble's "time" value is updated.

_scribble_array[@ __SCRIBBLE.TIME] = current_time;

I guess that's all right, but when it comes to autotype, it checks the scribble's delta time before actually updating it. I suppose this makes sense, because if you would try to draw the scribble multiple times in one step, it would update more times than it's supposed to. Unfortunately, when I try to draw the scribble for real immediately afterward pre-caching it (or fetching the cached version), the Scribble's delta time is always going to be zero

var _increment_timers = ((current_time - _scribble_array[__SCRIBBLE.TIME]) > __SCRIBBLE_EXPECTED_FRAME_TIME);

and the scribble autotype position remains in the purgatorial state of 0 for the [FGothic][shake][rainbow]rest of eternity.[]


My guess at what the solution to this should be would be to only set _scribble_array[@ __SCRIBBLE.TIME] (a) when the scribble is created or (b) when it's actually vertex_submitted so that it doesn't interfere with madmen like me who like to use it as a way to invisibly fetch stuff from the cache, but I don't know if there are any other reasons the time value would need to be set or not.

Add method to escape formatting tags

For debug and tutorialising it's useful to be able to draw text that has formatting tags written out in plaintext without applying the formatting e.g.

This text is not [wave]formatted[]

The suggested method to achieve this is to use a double open bracket to escape a formatting tag:

This text is not [[wave]formatted[[]

scribble_cache_group_flush not flushing

On the line (currently 39) where the script checks _scribble_array[__SCRIBBLE.FREED] as part of determining whether a scribble should be cleared or not, it looks like it should check the opposite !_scribble_array[__SCRIBBLE.FREED] instead, since the scribble otherwise won't enter the freed state to begin with and vertex buffers will never actually be deleted when you ask them to.

Next, the scribble doesn't get removed from the global cache map so if you try to create a scribble with a string that has already been flushed it will return an array with an already-deleted vertex buffer and nag you about drawing an invalid scribble. Adding ds_map_delete(global.__scribble_global_cache_map, _list[| _i]); to line 35 after the scribble has been fetched from the global map seems to take care of this, but I don't know if there are any other parts to this I'm missing so far.

Empty line break with new word breaking in v5.1.0

The new wrapping behaviour in 5.1.0 sometimes adds an empty line break to the beginning of the string. See this example:

This is the relevant code (simplified):

// Create scribble structure
// ...
scribble_draw_set_wrap(-1, 120);
scribble_element = scribble_draw(0, 0, content);
    
scribble_autotype_fade_in(scribble_element, SCRIBBLE_AUTOTYPE_PER_CHARACTER, tw_speed, 0);
    
scribble_draw_reset();

scribble_get_bbox(scribble_element, 0, 0) output for string "123456789ABCDEFG" is [ 0, 0, 123, 0, 0, 32, 123, 32 ] for the per-word version and [ 0, 0, 116, 0, 0, 32, 116, 32 ] for the per-character version. The content variable however does not have the line break, making me think this has something to do with the new word wrapping and the max width parameter.

Mandatory "Fonts" folder in Included Files

With scribble_init_start(), a font directory needs to be specified, even if only sprite fonts are ever used. Furthermore, the directory has to contain at least one file.
The given error (Line 22 in scribble_init_start()) outputs an unrelated and, at least on my system, not existing folder in AppData as the problem (using game_save_id).

I solved this error temporarily by adding a "Fonts" folder and a dummy file to my included files.

Specs: GMS2 v2.2.1.375, Runtime 2.2.1.287, Windows 10 1809

Scribble_autotype_set_sound script only working once and not playing the sound again

I have scribble being used in a text object that is called on whenever the player hits the enter key near an NPC. When I call Text object the first time the scribble_autotype_set_sound script works and the sound plays but when scribble is called for the second time the text object the scribble_autotype_set_sound script won't work, it just stays silent, even though its being called. It only works the first time I boot the game up.

Sprites draw themselves in weird places when the origin isn't (0, 0) (again)

Seems to be similar to #10, I don't know if it's the same problem that's come back or if it's a shiny new one.

If a sprite's origin is set to the upper-left, it looks fine.

image

Yes I spelled "aperture" wrong, don't judge me.

If it's in the center, it starts looking a bit off.

image

If it's all the way at the bottom-right, it's way out in deep right field.

image

Code:

scribble_draw_set_wrap(32, 1200);
scribble_draw_set_cache_group(0, false, true);
scribble_draw(32, 32, "Apeture Science (sic), we do what we must because we can.\n\nFor the good of all of us, except the ones who are [spr_dead]");
scribble_autotype_fade_in(scribble, SCRIBBLE_TYPEWRITER_PER_CHARACTER, 0.125, 1);
scribble_draw_reset();

Keeping the sprite origin in the upper-left seems to align it correctly in all conceivable real-world use cases, which is to say it's automatically centered with the text, but if you have a sprite that you want to use both in Scribble and somewhere else in the project and you want it to have a different sprite origin, problems might start occurring.

Improve font autoscan to work cross-platform

The autoscan feature currently use file functions to recursively scan Included Files for fonts. It's probably possible to automatically scan for and load fonts without using these functions, instead using the list of fonts as a guide.

Sprites draw themselves in weird places when the origin isn't (0, 0)

Scribble tries to center in-text sprites that it draws, but if the origin isn't in the upper-left - say, in the center, for example - it doesn't quite know what to do.

[spr_xbox][spr_keyboard]Show Info

where spr_xbox originates at (0, 0) and spr_keyboard originates in the center, you get this:

this is probably not intended behavior

instead of this:

much better

Scaled text is always fa_top

First off, scribble is awesome!
I was messing around with the features, and I noticed scaling text in the middle of a line always results in vertical alignment to be "fa_top", regardless of any align settings provided.
image

Is there any way to fix this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.