Skip to content

Commit

Permalink
Fix issue where fonts referenced from plugins were not always being i…
Browse files Browse the repository at this point in the history
…ncluded in compiled game
  • Loading branch information
chrismaltby committed Apr 30, 2024
1 parent 5d784b1 commit 699ea5e
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 84 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fix issue where variables in Dialogue and Math inputs could appear above script tabs
- Fix calculation of last parallax layer height in editor input [@pau-tomas](https://github.com/pau-tomas)
- Fix compiler warning when using some unary operators in While loop [@pau-tomas](https://github.com/pau-tomas)
- Fix issue where fonts referenced from plugins were not always being included in compiled game

## [3.2.1] - 2024-02-27

Expand Down
92 changes: 18 additions & 74 deletions src/lib/compiler/compileData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,8 @@ import {
Palette,
Scene,
ScriptEvent,
SoundData,
SpriteSheetData,
TilesetData,
Variable,
} from "shared/lib/entities/entitiesTypes";
import type { Dictionary } from "@reduxjs/toolkit";
import type {
Expand Down Expand Up @@ -936,7 +934,7 @@ export const precompileMusic = (
};

export const precompileFonts = async (
fonts: FontData[],
usedFonts: FontData[],
scenes: Scene[],
customEventsLookup: Dictionary<CustomEvent>,
defaultFontId: string,
Expand All @@ -947,10 +945,7 @@ export const precompileFonts = async (
warnings: (msg: string) => void;
}
) => {
const defaultFont =
fonts.find((font) => font.id === defaultFontId) || fonts[0];

if (!defaultFont) {
if (usedFonts.length === 0) {
await ensureProjectAsset("assets/fonts/gbs-mono.png", {
projectRoot,
warnings,
Expand All @@ -962,59 +957,6 @@ export const precompileFonts = async (
throw new Error(l10n("ERROR_MISSING_FONTS"));
}

const usedFontIds = [defaultFont.id];

const addFont = (id: string) => {
// If never seen this font before add it to the list
if (usedFontIds.indexOf(id) === -1) {
usedFontIds.push(id);
}
};

const addFontsFromString = (s: string) => {
(s.match(/(!F:[0-9a-f-]+!)/g) || [])
.map((id) => id.substring(3).replace(/!$/, ""))
.forEach(addFont);
};

walkScenesScripts(
scenes,
{
customEvents: {
lookup: customEventsLookup,
maxDepth: MAX_NESTED_SCRIPT_DEPTH,
},
},
(cmd) => {
if (cmd.args && cmd.args.fontId !== undefined) {
addFont(ensureString(cmd.args.fontId, fonts[0].id));
}
if (cmd.args && cmd.args.text !== undefined) {
// Add fonts referenced in text
addFontsFromString(String(cmd.args.text));
}
if (cmd.command && cmd.command === "EVENT_MENU" && cmd.args) {
// Add fonts referenced in menu items
const itemsLen = ensureNumber(cmd.args.items, 0);
for (let i = 1; i <= itemsLen; i++) {
addFontsFromString(String(cmd.args[`option${i}`]));
}
}
if (eventHasArg(cmd, "references")) {
const referencedIds = ensureReferenceArray(cmd.args?.references, [])
.filter((ref) => ref.type === "font")
.map((ref) => ref.id);
usedFontIds.push(...referencedIds);
}
}
);

const usedFonts: FontData[] = [defaultFont].concat(
fonts.filter((font) => {
return font.id !== defaultFont.id && usedFontIds.indexOf(font.id) > -1;
})
);

const fontData = await compileFonts(usedFonts, projectRoot);

return { usedFonts: fontData };
Expand Down Expand Up @@ -1236,6 +1178,7 @@ export const precompileScenes = (
const precompile = async (
projectData: ProjectData,
projectRoot: string,
scriptEventHandlers: ScriptEventHandlers,
tmpPath: string,
{
progress,
Expand All @@ -1246,22 +1189,17 @@ const precompile = async (
}
) => {
const customEventsLookup = keyBy(projectData.customEvents, "id");
const variablesLookup = keyBy(projectData.variables, "id");
const soundsLookup = keyBy(projectData.sounds, "id");
const colorMode = projectData.settings.colorMode;
const cgbOnly = colorMode === "color";

const usedAssets = determineUsedAssets({
scenes: projectData.scenes,
projectData,
customEventsLookup,
variablesLookup,
soundsLookup,
scriptEventHandlers,
});

progress(EVENT_MSG_PRE_VARIABLES);
const usedVariables = Object.values(
usedAssets.usedVariablesLookup
) as Variable[];
const usedVariables = usedAssets.referencedVariables;

progress(EVENT_MSG_PRE_IMAGES);
const {
Expand Down Expand Up @@ -1346,7 +1284,7 @@ const precompile = async (

progress(EVENT_MSG_PRE_FONTS);
const { usedFonts } = await precompileFonts(
projectData.fonts,
usedAssets.referencedFonts,
projectData.scenes,
customEventsLookup,
projectData.settings.defaultFontId,
Expand Down Expand Up @@ -1380,7 +1318,7 @@ const precompile = async (
backgroundLookup
);

const usedSounds = Object.values(usedAssets.usedSoundsLookup) as SoundData[];
const usedSounds = usedAssets.referencedSounds;

progress(EVENT_MSG_PRE_COMPLETE);

Expand Down Expand Up @@ -1449,10 +1387,16 @@ const compile = async (
);
}

const precompiled = await precompile(projectData, projectRoot, tmpPath, {
progress,
warnings,
});
const precompiled = await precompile(
projectData,
projectRoot,
scriptEventHandlers,
tmpPath,
{
progress,
warnings,
}
);

const colorEnabled = projectData.settings.colorMode !== "mono";
const isCGBOnly = projectData.settings.colorMode === "color";
Expand Down
64 changes: 54 additions & 10 deletions src/lib/compiler/precompile/determineUsedAssets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,33 @@ import { MAX_NESTED_SCRIPT_DEPTH } from "consts";
import { eventHasArg } from "lib/helpers/eventSystem";
import type {
CustomEvent,
Scene,
FontData,
// Scene,
SoundData,
Variable,
} from "shared/lib/entities/entitiesTypes";
import { EVENT_SOUND_PLAY_EFFECT } from "consts";
import { walkScenesScripts } from "shared/lib/scripts/walk";
import { ScriptEventHandlers } from "lib/project/loadScriptEventHandlers";
import type { ProjectData } from "store/features/project/projectActions";
import keyBy from "lodash/keyBy";

export const determineUsedAssets = ({
scenes,
variablesLookup,
soundsLookup,
projectData,
customEventsLookup,
scriptEventHandlers,
}: {
scenes: Scene[];
variablesLookup: Dictionary<Variable>;
soundsLookup: Dictionary<SoundData>;
projectData: ProjectData;
customEventsLookup: Dictionary<CustomEvent>;
scriptEventHandlers: ScriptEventHandlers;
}) => {
const variablesLookup = keyBy(projectData.variables, "id");
const soundsLookup = keyBy(projectData.sounds, "id");
const fontsLookup = keyBy(projectData.fonts, "id");

const usedVariablesLookup: Dictionary<Variable> = {};
const usedSoundsLookup: Dictionary<SoundData> = {};
const usedFontsLookup: Dictionary<FontData> = {};

const addAssetById =
<T>(assetLookup: Dictionary<T>, usedLookup: Dictionary<T>) =>
Expand All @@ -32,6 +39,7 @@ export const determineUsedAssets = ({
if (asset && !usedLookup[id]) {
usedLookup[id] = asset;
}
return !!asset;
};

const addVariableById = (id: string) => {
Expand All @@ -50,6 +58,14 @@ export const determineUsedAssets = ({
};
const addSoundById = addAssetById(soundsLookup, usedSoundsLookup);

const addFontById = addAssetById(fontsLookup, usedFontsLookup);

const addFontsFromString = (s: string) => {
(s.match(/(!F:[0-9a-f-]+!)/g) || [])
.map((id) => id.substring(3).replace(/!$/, ""))
.forEach(addFontById);
};

const addReferences = (
references: Reference[],
filterType: string,
Expand All @@ -63,8 +79,15 @@ export const determineUsedAssets = ({
}
};

// Add default font
if (!addFontById(projectData.settings.defaultFontId)) {
if (projectData.fonts.length > 0) {
addFontById(projectData.fonts[0].id);
}
}

walkScenesScripts(
scenes,
projectData.scenes,
{
customEvents: {
lookup: customEventsLookup,
Expand All @@ -84,11 +107,32 @@ export const determineUsedAssets = ({
const type = (cmd.args?.type as string) ?? "";
addSoundById(type);
}

if (cmd.args) {
for (const key in cmd.args) {
const value = cmd.args[key];
const fieldType =
scriptEventHandlers[cmd.command]?.fieldsLookup[key]?.type;

if (fieldType === "textarea" && typeof value === "string") {
// String text fields
addFontsFromString(value);
} else if (fieldType === "textarea" && Array.isArray(value)) {
// Multi value text fields
for (const row of value) {
if (typeof row === "string") {
addFontsFromString(row);
}
}
}
}
}
}
);

return {
usedVariablesLookup,
usedSoundsLookup,
referencedVariables: Object.values(usedVariablesLookup) as Variable[],
referencedSounds: Object.values(usedSoundsLookup) as SoundData[],
referencedFonts: Object.values(usedFontsLookup) as FontData[],
};
};

0 comments on commit 699ea5e

Please sign in to comment.