The script has two purposes:
remove orphan words
alphabetize the files
I set it up to run on GitHub action as a checker, but a --fix option is available as well for running locally.
When running, I noticed that there are A LOT of orphaned words.
At first, I thought that it might be the case that cSpell was missing words on our docs that were clearly used, which would be a HUGE issue. I made this PR to validate that: #2735
But upon proper investigation, and using cSpell's trace command, I realized that we import multiple standard dictionaries: "en_US" and "softwareTerms", and they are constantly being updated. The word "cypher" was just added 12 hours ago, for example.
Turns out ALL of the current orphan words are properly being detected on our files, but now are included on the official dictionaries! Which is amazing.
Note that I did have to stop using the GitHub Action to run cSpell. The reason is twofold; (1) because I need to install cSpell anyway to run my script and didn't want to have the action download it again; and (2) because the version on the GitHub Action (even though it is the same 7.3.7 from npm that I have locally) doesn't have the latest updates (like does not have the cypher word that was added 12h ago). This would make my script and the CI script incompatible.
When the init game method is called straight after the app has launched, the lifecycle state from WidgetsBinding.instance.lifecycleState often returns disposed or inactive which causes the engine to stay paused even though the app is foregrounded.
This PR fixes the lifecycle state as resumed when the init method is called.
Fix `TextBoxComponent` alignment bug
The `anchor` is the anchor of the text box component itself.
It has nothing to do with the alignment of the text within the box.
The position computed for rendering the text on the above lines is
assuming `topLeft` anchor for the text.
The removeFromParent wasn't going through the public methods on the parent, so overwriting the remove would not allow you to detect all removing of children.
I suggest changing the child element of the Align component. In this case, the child element is not a required parameter.
Motivation:
Thus, the Align component can be created as a class field.
We can replace the child at any time.
Hello:
I can create a label field on a button and change the label depending on the state of the button.
The new camera systems seems to have uncovered a bug in the flame_tiled parallax calculations. The camera zoom levels need to be scaled by the tile size to by applied in the correct coordinate space. I've mostly validated this manually by comparing the Tiled application's viewport to a Flame game at runtime.
Since FlameGame now takes in `W extends World` the mixins that are `on FlameGame` needs to be able to take in the same generics.
Later the `HasKeyboardHandlerComponents` wont be necessary, but let's do this intermediary step.
Since the widget wasn't refreshed when a new mouse detector was added it only worked if for example HoverCallbacks components were added directly in the game's onLoad.
This PR no longer treats it as an invalid action to add a child to a
parent even if it already has a parent, it simply triggers a move
instead, which makes it possible to simplify the logic.
When the game is backgrounded and then resumed, the update function is called with a very large dt time step.
This might cause the physics engine to hit the maximum translation per timestep, causing moving bodies to slow down to almost-zero velocities.
This PR makes the game pause if the game is backgrounded. If you'd like to change this behaviour, set the pauseWhenBackgrounded flag to true (default) or false.
class MyGame extends FlameGame {
MyGame() {
pauseWhenBackgrounded = false;
}
}
This is currently not working on the web, see flutter/flutter#53107.
You can view previous discussion about this here: flame-engine/forge2d#84.
Adds a mixin for components similar to `HasAncestor`, `HasParent` and
`HasGameReference` but which provides access to the `World` which the
component has as an ancestor.
<!--
The title of your PR on the line above should start with a [Conventional
Commit] prefix
(`fix:`, `feat:`, `docs:`, `test:`, `chore:`, `refactor:`, `perf:`,
`build:`, `ci:`,
`style:`, `revert:`). This title will later become an entry in the
[CHANGELOG], so please
make sure that it summarizes the PR adequately.
-->
# Description
<!--
Provide a description of what this PR is doing.
If you're modifying existing behavior, describe the existing behavior,
how this PR is changing it,
and what motivated the change. If this is a breaking change, specify
explicitly which APIs were
changed.
-->
It was already possible to update the prefixes of FlameAudio assets, but
it required a certain understanding of `FlameAudio` and `Audioplayers`.
This PR adds a simple helper method that makes it easier to change
without requiring much context of the internals of the package.
## Checklist
<!--
Before you create this PR confirm that it meets all requirements listed
below by checking the
relevant checkboxes with `[x]`. If some checkbox is not applicable, mark
it as `[-]`.
-->
- [x] I have followed the [Contributor Guide] when preparing my PR.
- [x] I have updated/added tests for ALL new/updated/fixed
functionality.
- [ ] I have updated/added relevant documentation in `docs` and added
dartdoc comments with `///`.
- [ ] I have updated/added relevant examples in `examples` or `docs`.
## Breaking Change?
<!--
Would your PR require Flame users to update their apps following your
change?
If yes, then the title of the PR should include "!" (for example,
`feat!:`, `fix!:`). See
[Conventional Commit] for details. Also, for a breaking PR uncomment and
fill in the "Migration
instructions" section below.
-->
- [ ] Yes, this PR is a breaking change.
- [x] No, this PR is not a breaking change.
<!--
### Migration instructions
If the PR is breaking, uncomment this header and add instructions for
how to migrate from the
currently released version to the new proposed way.
-->
## Related Issues
<!--
Indicate which issues this PR resolves, if any. For example:
Closes#1234
!-->
<!-- Links -->
[Contributor Guide]:
https://github.com/flame-engine/flame/blob/main/CONTRIBUTING.md
[Conventional Commit]: https://conventionalcommits.org
[CHANGELOG]:
https://github.com/flame-engine/flame/blob/main/CHANGELOG.md
I would like to suggest to add option to load atlas without compression as simple json file.
I found it useful to use for example in itch.io, where gzip encoder causes an error during decoding.
The FlameGame lifecycle diagram is incorrect. The lifecycle for a FlameGame is as follows:
onGameResize
onLoad
onMount
render
update
onRemove
onGameResize
onLoad
onMount
render
update
Note in particular the onGameResize is before onLoad and the render and update are reversed. Because they are different, this PR creates a new lifecycle diagram that is not shared with Component. It also fixes the Component lifecycle diagram to be consistent with the FlameGame lifecycle diagram formatting and terms.
This implements a Snapshot mixin on PositionComponent that allows:
A component to be rendered once then cached (for performance)
and/or a Picture or Image snapshot to be taken at any time
Internally the snapshot is cached and redrawn as a Picture. After testing with both Image and Picture I found that Image had no performance improvement, and the rendering quality was lower.
A helper method snapshotToImage was added to allow the user better control of generating an Image from the internal Picture snapshot if that is desired.
See the documentation in this PR for more details.
# Description
The priority is set to the max here to avoid some bugs for the users,
if they for example would add any components that modify positions
before the CameraComponent, since it then will render the positions
of the last tick each tick.
## Checklist
<!--
Before you create this PR confirm that it meets all requirements listed
below by checking the
relevant checkboxes with `[x]`. If some checkbox is not applicable, mark
it as `[-]`.
-->
- [x] I have followed the [Contributor Guide] when preparing my PR.
- [x] I have updated/added tests for ALL new/updated/fixed
functionality.
- [x] I have updated/added relevant documentation in `docs` and added
dartdoc comments with `///`.
- [x] I have updated/added relevant examples in `examples` or `docs`.
## Breaking Change?
<!--
Would your PR require Flame users to update their apps following your
change?
If yes, then the title of the PR should include "!" (for example,
`feat!:`, `fix!:`). See
[Conventional Commit] for details. Also, for a breaking PR uncomment and
fill in the "Migration
instructions" section below.
-->
- [x] No, this PR is not a breaking change.
<!--
### Migration instructions
If the PR is breaking, uncomment this header and add instructions for
how to migrate from the
currently released version to the new proposed way.
-->
## Related Issues
Found in #2583
<!-- Links -->
[Contributor Guide]:
https://github.com/flame-engine/flame/blob/main/CONTRIBUTING.md
[Conventional Commit]: https://conventionalcommits.org
[CHANGELOG]:
https://github.com/flame-engine/flame/blob/main/CHANGELOG.md
According to the Flutter docs, tests and #2551 FilterQuality.high is actually producing worse output than FilterQuality.medium in almost all cases (the exception is when you use a very high scale factor).
This PRs set the places we have defined as high to medium instead.
Since `globalToLocal` and `localToGlobal` are called a lot when gestures
are being triggered we should try to minimize the amount of new Vector2
objects created here.
Improve our spellchecker (cspell) configuration and dictionary file
organization.
# Rationale
This is a proposal to establish a few changes:
* better separate our dictionary files into different categories of
types of words we are including
* improve the cspell regexes to be more aggressive
* be less lenient to what kinds of words we are adding to our
dictionaries
* have the dictionary file also serve as an explanation for obscure
references that cannot be easily derived from the word
Essentially my goal is that either when reviewing a PR that adds a new
entry to our dictionary, or when reading the dictionary files
themselves, it is immediately obvious what the entries are and why they
are there. Currently it can be just a dumpster we throw anything into if
spellcheck fails.
# Proposal
This PR-as-a-proposal essentially do the following changes.
## Split Dictionary Files
Proposes a better separation for our dictionary files. Currently we have
3 that are a bit broad and not super clear on what goes where. This
breaks it down a bit more and adds a comment to each file explaining
what kinds of terms should be added to each; that also serves as a
general guidance for what kinds of words should be added to the lexicon
in general, and makes it harder for mistakes to make into it.
* `flame_dictionary`: remains pretty much unchanged; it is dedicated to
Flame-related words, including companies, tools, and libraries (and
their associated concepts) mentioned on our codebase. Basically a
collection of proper-nouns relating to companies and libraries we
mention.
* `dart_dictionary`: new file for Dart and Flutter related terms
* `sphinx_dictionary`: unchanged, for Sphynx related terms
* `people_dictionary`: specific for people names and usernames
referenced on the codebase (in TODOs, mentions, etc)
* `words_dictionary`: actual English-language words (or common
abbreviations) missing from CSpell
* `gamedev_dictionary`: this was our biggest file that contained all
sort of things. it has been mostly broken down and now only contains
general development-adjacent terms and expressions
## Include definitions
Except for the `words` dictionary, which should be self-explanatory (as
it basically covers for "holes" in CSpell standard dictionary, which I
have been finding a bit lacking), every other file will contain terms in
the form:
```
word # definition of the word
```
What exactly the definition is can slightly vary depending on which
dictionary file we are talking about, but the examples should be
self-explanatory.
As an example, for the gamedev file, it should provide some simple
guidance as to what the term means, or if it's an acronym or
abbreviation, what it stands for. The goal is not to teach the entire
concept to someone unfamiliar, but allow them to "google" it for
themselves by giving enough context, so they can confirm their
suspicions. For example, if they see `LTRB` somewhere by itself, they
are not able to "just google that" because it is too vague. The
dictionary file provides enough context for the user to figure out
however much deeper information they want about any particular subject.
It will also disambiguate from any non-Flame related homonyms. For
people on the people file and companies on the flame file, the
description will provide links to clearly disambiguate what they are;
for tools, a brief description of what the tool is for is also included.
And so on.
The goal is not to build a comprehensive, in depth-guide to each word we
use, but rather to give the bare minimum of context on what this term
"is doing" on our codebase.
## Be less lenient with terms
My idea with these two major changes combined, is that we are overall
more tactical about which terms we want to add to the dictionaries.
Adding a word to the dictionary file is essentially giving carte blanche
to anyone in the future to reuse that term anywhere. I think we should
see spellchecker violations as "warnings"; we decide on the set of
warning rules we want to enable for the entire project (hopefully all
the ones that make sense; or have a reason for disabling the ones that
don't). We might need to violate these warnings sporadically, for
example, we ban `print` on the codebase but might need to allow it
specifically in a couple places. But we would not disable the entire
warning to do that, rather we would add a specific comment-bypass on the
smallest possible scope that encompasses all the relevant lines. We
would also add a proper comment explaining why we are bypassing the
general rule in this specific place.
Similarly, we should not have one-off violations on the dictionary file,
even if they make sense in the one place they occur, but we should
encourage more liberal use of scoped bypasses for such cases. These
Ukrainian words are required in this file, but should not be on the
dictionary as it does not make sense to use foreign languages anywhere
else:
```
// used as examples of Ukrainian words on the documentation below
// cSpell:ignore рушниця, рушниці, рушниць
```
It might look inelegant to have to include that, but just like a
warning-bypass comment, accompanied by the explanatory proper-comment,
this actually provides helpful guidance and context for the reader that
might be confused with the usage of incomprehensible terms.
This also encourages people to avoid obscure terms that are not already
in our dictionary (i.e. that we have already "bought in" and paid the
mental load investment cost), making our code (and docs) easier to parse
and read for everyone. I want to be extremely clear that that **does
not** mean we need to "dumb down" anything whatsoever, or do any sort of
gymnastics to avoid the wrath of an incompetent spellchecker.
But, for example [when spelling "cave
ace"](https://github.com/flame-engine/flame/pull/2304) in variable names
in a random example, having it typed as `caveAce` instead of `caveace`
can slightly help with readability, specially for non-native speakers
(like most of us). It is an extremely minor insignificant gain, but
having the dictionary file require a brief description will nudge us to
give a bit more thought into each "bypass" we are adding.
(note: a similar issue that I have not yet addressed is "spine boy", but
I will leave that for followups and just added that one to the
dictionary for now, as I am still over the fence on that one since it is
an actual "known" character with a dedicated page, so it is more like a
proper noun - as a specific decision I think it is out-of-scope of the
broader discussion).
flutter format will generate a deprecation warning:
The "format" command is deprecated. Please use the "dart format" sub-command instead, which has the same command-line usage as "flutter format".
It should be replaced with dart format.
Have updated two places in the docs, and in a shell script (please verify this one for me!)
It doesn't make any sense for HasGameReference to have Game as a base instead of FlameGame since the mixin is on Component and clearly in a component tree context, so this PR sets the base to be FlameGame (like HasGameRef).
Allow functions and commands to be removed from storage, or function and/or command storage to be cleared.
This is useful if different parts of the game have different implementations of a command or a function. Currently registering a function or command with the same name fails (i.e. it is not overwritten). Removing the function or command allows it to be replaced.
Allow variables to be removed from variable storage, or variable storage to be cleared.
It's not usual to do this, but could be useful in large games where each scene may have its own set of variables. They can be cleared between scenes. Another use-case is for implementing a 'save game' feature. The variables can be cleared, and a new set of variables loaded in from a save game.
It's important to note that Jenny uses variable storage to retain the node visit counts (the number of times the player has visited each node). This has been taken into account in the clear method, which allows the user to retain the node visit counts.
Allow characters to be removed from character storage, or character
storage to be cleared.
This is useful in large games where each scene may have different sets
of characters. They can be cleared between scenes, and new characters
loaded.