@jjlmoya/utils-games-development 1.62.0 → 1.64.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/category/index.ts +3 -1
- package/src/entries.ts +7 -1
- package/src/index.ts +2 -0
- package/src/tests/locale_completeness.test.ts +2 -2
- package/src/tests/tool_validation.test.ts +2 -2
- package/src/tool/damageFormulaLab/bibliography.astro +24 -0
- package/src/tool/damageFormulaLab/bibliography.ts +10 -0
- package/src/tool/damageFormulaLab/component.astro +178 -0
- package/src/tool/damageFormulaLab/controller.ts +235 -0
- package/src/tool/damageFormulaLab/damage-formula-lab.css +644 -0
- package/src/tool/damageFormulaLab/dom-views.ts +193 -0
- package/src/tool/damageFormulaLab/entry.ts +28 -0
- package/src/tool/damageFormulaLab/evaluator.ts +84 -0
- package/src/tool/damageFormulaLab/expression.ts +191 -0
- package/src/tool/damageFormulaLab/i18n/de.ts +181 -0
- package/src/tool/damageFormulaLab/i18n/en.ts +231 -0
- package/src/tool/damageFormulaLab/i18n/es.ts +181 -0
- package/src/tool/damageFormulaLab/i18n/fr.ts +181 -0
- package/src/tool/damageFormulaLab/i18n/id.ts +181 -0
- package/src/tool/damageFormulaLab/i18n/it.ts +181 -0
- package/src/tool/damageFormulaLab/i18n/ja.ts +182 -0
- package/src/tool/damageFormulaLab/i18n/ko.ts +181 -0
- package/src/tool/damageFormulaLab/i18n/nl.ts +181 -0
- package/src/tool/damageFormulaLab/i18n/pl.ts +181 -0
- package/src/tool/damageFormulaLab/i18n/pt.ts +181 -0
- package/src/tool/damageFormulaLab/i18n/ru.ts +181 -0
- package/src/tool/damageFormulaLab/i18n/sv.ts +181 -0
- package/src/tool/damageFormulaLab/i18n/tr.ts +181 -0
- package/src/tool/damageFormulaLab/i18n/zh.ts +181 -0
- package/src/tool/damageFormulaLab/index.ts +11 -0
- package/src/tool/damageFormulaLab/logic.test.ts +138 -0
- package/src/tool/damageFormulaLab/logic.ts +138 -0
- package/src/tool/damageFormulaLab/model.ts +151 -0
- package/src/tool/damageFormulaLab/seo.astro +13 -0
- package/src/tool/damageFormulaLab/storage.ts +62 -0
- package/src/tool/damageFormulaLab/transfers.ts +89 -0
- package/src/tool/damageFormulaLab/ui.ts +62 -0
- package/src/tool/hitboxHurtboxAnimator/bibliography.astro +12 -0
- package/src/tool/hitboxHurtboxAnimator/bibliography.ts +10 -0
- package/src/tool/hitboxHurtboxAnimator/canvas-interactions.ts +59 -0
- package/src/tool/hitboxHurtboxAnimator/canvas-metrics.ts +8 -0
- package/src/tool/hitboxHurtboxAnimator/component.astro +148 -0
- package/src/tool/hitboxHurtboxAnimator/controller.ts +247 -0
- package/src/tool/hitboxHurtboxAnimator/dom-views.ts +194 -0
- package/src/tool/hitboxHurtboxAnimator/editor-state.ts +19 -0
- package/src/tool/hitboxHurtboxAnimator/entry.ts +28 -0
- package/src/tool/hitboxHurtboxAnimator/evaluator.ts +15 -0
- package/src/tool/hitboxHurtboxAnimator/file-io.ts +82 -0
- package/src/tool/hitboxHurtboxAnimator/hitbox-hurtbox-animator.css +614 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/de.ts +195 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/en.ts +191 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/es.ts +195 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/fr.ts +195 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/id.ts +195 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/it.ts +195 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/ja.ts +195 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/ko.ts +195 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/nl.ts +195 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/pl.ts +195 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/pt.ts +195 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/ru.ts +195 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/sv.ts +195 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/tr.ts +195 -0
- package/src/tool/hitboxHurtboxAnimator/i18n/zh.ts +195 -0
- package/src/tool/hitboxHurtboxAnimator/index.ts +11 -0
- package/src/tool/hitboxHurtboxAnimator/logic.test.ts +97 -0
- package/src/tool/hitboxHurtboxAnimator/logic.ts +173 -0
- package/src/tool/hitboxHurtboxAnimator/project-actions.ts +128 -0
- package/src/tool/hitboxHurtboxAnimator/seo.astro +13 -0
- package/src/tool/hitboxHurtboxAnimator/storage.ts +27 -0
- package/src/tool/hitboxHurtboxAnimator/ui.ts +70 -0
- package/src/tools.ts +4 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import type { FAQPage, HowTo, SoftwareApplication, WithContext } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { DamageFormulaLabUI } from '../ui';
|
|
4
|
+
import { bibliographyEntries } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'kalkulator-formula-damage-game-ttk';
|
|
7
|
+
const title = 'Kalkulator Formula Damage Game dan Grafik TTK';
|
|
8
|
+
const description = 'Bandingkan formula damage game secara langsung melalui kurva interaktif, peta panas serangan dan pertahanan, pembulatan nilai, serta Time to Kill (TTK).';
|
|
9
|
+
|
|
10
|
+
const faq = [
|
|
11
|
+
{
|
|
12
|
+
question: 'Apa saja yang dibandingkan oleh kalkulator formula damage ini?',
|
|
13
|
+
answer: 'Alat ini menguji dua formula matematika aman dengan variabel pertarungan yang sama. Anda dapat membandingkan kurva damage, ambang jumlah pukulan, time to kill (TTK), aturan pembulatan, dan urutan resistensi.',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
question: 'Variabel dan fungsi apa saja yang dapat saya gunakan?',
|
|
17
|
+
answer: 'Variabel yang tersedia adalah attack, defense, level, power, resistance, flat, criticalChance, dan criticalMultiplier. Fungsi aman yang didukung meliputi min, max, clamp, abs, sqrt, pow, floor, round, dan ceil.',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
question: 'Bagaimana cara menghitung Time to Kill (TTK)?',
|
|
21
|
+
answer: 'Jumlah pukulan dihitung dari darah target dibagi damage yang diharapkan (dibulatkan ke atas). TTK dihitung dari interval antar pukulan: (pukulan - 1) / serangan per detik.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
question: 'Mengapa urutan resistensi mempengaruhi hasil kalkulasi?',
|
|
25
|
+
answer: 'Menerapkan nilai pengurang tetap sebelum persentase resistensi akan mengurangi dampak pengurang tetap tersebut. Jika resistensi diterapkan lebih dulu, nilai pengurang tetap tidak terpengaruh.',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
question: 'Apakah kurva yang mulus menjamin keseimbangan game?',
|
|
29
|
+
answer: 'Tidak. Kurva membantu menemukan daerah tanpa damage dan lonjakan ekstrem, tetapi keseimbangan permainan tetap bergantung pada pengujian langsung dan peran karakter.',
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
const howTo = [
|
|
34
|
+
{ name: 'Pilih dua formula', text: 'Gunakan templat dasar (linier, rasio, atau skala level) atau masukkan dua formula kustom.' },
|
|
35
|
+
{ name: 'Atur variabel pertarungan', text: 'Masukkan nilai attack, defense, level, koefisien power, persentase resistensi, pengurang tetap, kritis, darah target, dan kecepatan serangan.' },
|
|
36
|
+
{ name: 'Tentukan aturan pembulatan', text: 'Pilih metode pembulatan damage dan urutan penerapan resistensi.' },
|
|
37
|
+
{ name: 'Analisis kurva dan grafik', text: 'Perhatikan grafik perbandingan damage, peta panas pertahanan, jumlah pukulan yang dibutuhkan, dan peringatan batas.' },
|
|
38
|
+
{ name: 'Simpan eksperimen', text: 'Salin tautan berbagi atau unduh berkas konfigurasi JSON, tabel CSV, atau gambar grafik PNG.' },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
const softwareApplication: WithContext<SoftwareApplication> = {
|
|
42
|
+
'@context': 'https://schema.org',
|
|
43
|
+
'@type': 'SoftwareApplication',
|
|
44
|
+
name: title,
|
|
45
|
+
applicationCategory: 'DeveloperApplication',
|
|
46
|
+
operatingSystem: 'Any',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const faqPage: WithContext<FAQPage> = {
|
|
50
|
+
'@context': 'https://schema.org',
|
|
51
|
+
'@type': 'FAQPage',
|
|
52
|
+
mainEntity: faq.map((item) => ({
|
|
53
|
+
'@type': 'Question',
|
|
54
|
+
name: item.question,
|
|
55
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
56
|
+
})),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const howToSchema: WithContext<HowTo> = {
|
|
60
|
+
'@context': 'https://schema.org',
|
|
61
|
+
'@type': 'HowTo',
|
|
62
|
+
name: title,
|
|
63
|
+
step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })),
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const content: ToolLocaleContent<DamageFormulaLabUI> = {
|
|
67
|
+
slug,
|
|
68
|
+
title,
|
|
69
|
+
description,
|
|
70
|
+
ui: {
|
|
71
|
+
onboarding: 'Masukkan formula yang Anda gunakan saat ini, sandingkan dengan formula alternatif, lalu sesuaikan status pertarungan.',
|
|
72
|
+
localNote: 'Model privat. Formula dan berkas diproses sepenuhnya di dalam peramban ini.',
|
|
73
|
+
formulaDeck: 'Area Formula',
|
|
74
|
+
formulaALabel: 'Formula A (Model Saat Ini)',
|
|
75
|
+
formulaBLabel: 'Formula B (Pembanding)',
|
|
76
|
+
formulaHint: 'Variabel: attack, defense, level, power, resistance, flat, criticalChance, criticalMultiplier',
|
|
77
|
+
formulaFunctions: 'Fungsi Aman: min, max, clamp, abs, sqrt, pow, floor, round, ceil',
|
|
78
|
+
presetLinear: 'Perlindungan Linier',
|
|
79
|
+
presetRatio: 'Armor Rasio',
|
|
80
|
+
presetLevel: 'Skala Level',
|
|
81
|
+
combatInputs: 'Status Pertarungan',
|
|
82
|
+
attackLabel: 'Attack',
|
|
83
|
+
defenseLabel: 'Defense',
|
|
84
|
+
levelLabel: 'Level',
|
|
85
|
+
powerLabel: 'Koefisien Power',
|
|
86
|
+
resistanceLabel: 'Persentase Resistensi',
|
|
87
|
+
flatLabel: 'Pengurang Tetap (Flat)',
|
|
88
|
+
criticalChanceLabel: 'Peluang Kritis (%)',
|
|
89
|
+
criticalMultiplierLabel: 'Pengganda Kritis',
|
|
90
|
+
healthLabel: 'Darah Target',
|
|
91
|
+
cadenceLabel: 'Serangan per Detik',
|
|
92
|
+
roundingLabel: 'Pembulatan Damage',
|
|
93
|
+
roundingNone: 'Simpan Desimal',
|
|
94
|
+
roundingFloor: 'Pembulatan Bawah (Floor)',
|
|
95
|
+
roundingRound: 'Angka Bulat Terdekat',
|
|
96
|
+
roundingCeil: 'Pembulatan Atas (Ceil)',
|
|
97
|
+
orderLabel: 'Urutan Modifikator',
|
|
98
|
+
resistanceFirst: 'Resistensi Lalu Pengurang Tetap',
|
|
99
|
+
flatFirst: 'Pengurang Tetap Lalu Resistensi',
|
|
100
|
+
runLabel: 'Perbandingan Dampak Langsung',
|
|
101
|
+
resultDamage: 'Damage Diharapkan',
|
|
102
|
+
resultHits: 'Pukulan untuk Menang',
|
|
103
|
+
resultTtk: 'Time to Kill (TTK)',
|
|
104
|
+
resultDifference: 'Selisih Damage',
|
|
105
|
+
formulaAName: 'Saat Ini',
|
|
106
|
+
formulaBName: 'Pembanding',
|
|
107
|
+
curveTitle: 'Tren Peningkatan Attack',
|
|
108
|
+
curveCaption: 'Grafik menunjukkan perubahan damage saat nilai attack dinaikkan dari setengah hingga dua kali lipat.',
|
|
109
|
+
heatmapTitle: 'Peta Panas Tekanan',
|
|
110
|
+
heatmapCaption: 'Setiap kotak menampilkan damage yang diharapkan dari Formula A pada kombinasi attack dan defense.',
|
|
111
|
+
attackAxis: 'Attack meningkat ke kanan',
|
|
112
|
+
defenseAxis: 'Defense meningkat ke bawah',
|
|
113
|
+
scenariosTitle: 'Skenario Pertarungan',
|
|
114
|
+
scenarioSkirmisher: 'Skirmisher',
|
|
115
|
+
scenarioGuardian: 'Guardian',
|
|
116
|
+
scenarioBoss: 'Boss',
|
|
117
|
+
scenarioCustom: 'Pengaturan Saat Ini',
|
|
118
|
+
diagnosticsTitle: 'Pemeriksaan Batas & Peringatan',
|
|
119
|
+
statusBalanced: 'Tidak ditemukan lonjakan matematis abnormal pada pengujian ini.',
|
|
120
|
+
exportTitle: 'Ekspor Hasil Eksperimen',
|
|
121
|
+
copyLink: 'Salin Tautan Berbagi',
|
|
122
|
+
exportCsv: 'Unduh CSV',
|
|
123
|
+
exportJson: 'Unduh JSON',
|
|
124
|
+
importJson: 'Impor JSON',
|
|
125
|
+
exportPng: 'Unduh Gambar PNG',
|
|
126
|
+
reset: 'Reset Model',
|
|
127
|
+
privacyDisclosure: 'Tautan berbagi menyimpan konfigurasi pada URL dan tidak dikirim ke server luar.',
|
|
128
|
+
limitationDisclosure: 'Nilai damage kritis adalah rata-rata statistik, bukan simulasi pertarungan acak.',
|
|
129
|
+
importError: 'Berkas tidak sesuai dengan format konfigurasi laboratorium damage.',
|
|
130
|
+
copiedStatus: 'Tautan berhasil disalin ke papan klip.',
|
|
131
|
+
},
|
|
132
|
+
seo: [
|
|
133
|
+
{
|
|
134
|
+
type: 'title',
|
|
135
|
+
level: 2,
|
|
136
|
+
text: 'Uji formula damage game sebelum diimplementasikan di mesin game',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
type: 'paragraph',
|
|
140
|
+
html: 'Formula damage mungkin terlihat seimbang pada nilai awal, namun dapat rusak pada level tinggi. Alat ini membantu Anda melihat daerah tanpa damage dan lonjakan nilai sebelum kode diterapkan.',
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
type: 'title',
|
|
144
|
+
level: 2,
|
|
145
|
+
text: 'Bahasa ekspresi yang aman dan terbatas',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
type: 'paragraph',
|
|
149
|
+
html: 'Bidang input hanya menerima variabel dan fungsi matematika yang ditentukan tanpa menjalankan skrip eksternal.',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
type: 'table',
|
|
153
|
+
headers: ['Metrik', 'Perhitungan', 'Tujuan Desain'],
|
|
154
|
+
rows: [
|
|
155
|
+
['Damage diharapkan', 'Formula dasar termasuk faktor kritis dan aturan pembulatan', 'Apakah formula bekerja konsisten pada karakter lemah maupun kuat?'],
|
|
156
|
+
['Pukulan untuk menang', 'Darah target dibagi damage yang dibulatkan', 'Apakah tambahan 1 poin stat menghilangkan 1 pukulan penuh yang dibutuhkan?'],
|
|
157
|
+
['Time to Kill (TTK)', 'Interval antar pukulan dibagi kecepatan serangan', 'Apakah ritme pertarungan sudah sesuai dengan rencana awal?'],
|
|
158
|
+
['Peta panas tekanan', 'Sampel Formula A pada variasi attack dan defense', 'Apakah ada area mati atau lonjakan yang tidak diharapkan?'],
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
type: 'title',
|
|
163
|
+
level: 2,
|
|
164
|
+
text: 'Memisahkan data matematika dari keputusan desain',
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
type: 'paragraph',
|
|
168
|
+
html: 'Grafik yang mulus bukan bukti bahwa permainan pasti menyenangkan. Gunakan laboratorium ini untuk menemukan parameter yang perlu diuji dalam sesi playtest.',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
type: 'tip',
|
|
172
|
+
title: 'Periksa damage dan jumlah pukulan secara bersamaan',
|
|
173
|
+
html: 'Perubahan kecil pada damage bisa saja melewati ambang batas darah target dan mengurangi 1 pukulan penuh. Selalu bandingkan nilai damage dengan jumlah pukulan dan TTK.',
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
faq,
|
|
177
|
+
bibliographyTitle: 'Referensi kalkulasi damage game',
|
|
178
|
+
bibliography: bibliographyEntries,
|
|
179
|
+
howTo,
|
|
180
|
+
schemas: [softwareApplication, faqPage, howToSchema],
|
|
181
|
+
};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import type { FAQPage, HowTo, SoftwareApplication, WithContext } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { DamageFormulaLabUI } from '../ui';
|
|
4
|
+
import { bibliographyEntries } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'calcolatore-formule-danno-giochi-ttk';
|
|
7
|
+
const title = 'Laboratorio Formule Danno e Grafici TTK';
|
|
8
|
+
const description = 'Confronta le formule di danno per videogiochi in tempo reale attraverso curve dinamiche, mappe di calore, arrotondamenti, colpi critici e Time to Kill (TTK).';
|
|
9
|
+
|
|
10
|
+
const faq = [
|
|
11
|
+
{
|
|
12
|
+
question: 'Cosa permette di confrontare il calcolatore di formule di danno?',
|
|
13
|
+
answer: 'Esegue due espressioni matematiche sicure sugli stessi valori di combattimento. Permette di confrontare curve di danno, soglie di colpi, time to kill (TTK), regole di arrotondamento e l ordine delle resistenze.',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
question: 'Quali variabili e funzioni si possono utilizzare?',
|
|
17
|
+
answer: 'Le variabili disponibili sono attack, defense, level, power, resistance, flat, criticalChance e criticalMultiplier. Le funzioni sicure sono min, max, clamp, abs, sqrt, pow, floor, round e ceil.',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
question: 'Come viene calcolato il Time to Kill (TTK)?',
|
|
21
|
+
answer: 'I colpi necessari sono dati dalla salute del bersaglio divisa per il danno previsto arrotondato (per eccesso). Il TTK misura l intervallo tra il primo e l ultimo colpo: (colpi - 1) / attacchi al secondo.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
question: 'Perché l ordine delle resistenze modifica il risultato?',
|
|
25
|
+
answer: 'Applicare un modificatore piatto prima della resistenza percentuale riduce anche quel valore piatto. Applicare prima la resistenza lascia invariato il modificatore piatto successivo.',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
question: 'Una curva uniforme garantisce un gioco bilanciato?',
|
|
29
|
+
answer: 'No. Una curva evidenzia zone a danno zero e discontinuità, ma il bilanciamento dipende dal contesto del gioco, dai ruoli e dai test con i giocatori.',
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
const howTo = [
|
|
34
|
+
{ name: 'Scegliere due formule', text: 'Parti da un modello predefinito (lineare, rapporto o livello) oppure inserisci due formule personalizzate.' },
|
|
35
|
+
{ name: 'Impostare lo stato di combattimento', text: 'Inserisci i valori di attacco, difesa, livello, potenza, resistenza, modificatore piatto, critici, salute e cadenza.' },
|
|
36
|
+
{ name: 'Definire le regole dell motore', text: 'Scegli la modalità di arrotondamento e stabilisci se la resistenza si applica prima o dopo il modificatore piatto.' },
|
|
37
|
+
{ name: 'Analizzare curve e soglie', text: 'Confronta la traiettoria di attacco, la mappa di calore, i colpi necessari e gli avvisi di diagnostica.' },
|
|
38
|
+
{ name: 'Esportare l esperimento', text: 'Copia un link di condivisione o scarica la configurazione JSON, la tabella CSV o l immagine PNG del grafico.' },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
const softwareApplication: WithContext<SoftwareApplication> = {
|
|
42
|
+
'@context': 'https://schema.org',
|
|
43
|
+
'@type': 'SoftwareApplication',
|
|
44
|
+
name: title,
|
|
45
|
+
applicationCategory: 'DeveloperApplication',
|
|
46
|
+
operatingSystem: 'Any',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const faqPage: WithContext<FAQPage> = {
|
|
50
|
+
'@context': 'https://schema.org',
|
|
51
|
+
'@type': 'FAQPage',
|
|
52
|
+
mainEntity: faq.map((item) => ({
|
|
53
|
+
'@type': 'Question',
|
|
54
|
+
name: item.question,
|
|
55
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
56
|
+
})),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const howToSchema: WithContext<HowTo> = {
|
|
60
|
+
'@context': 'https://schema.org',
|
|
61
|
+
'@type': 'HowTo',
|
|
62
|
+
name: title,
|
|
63
|
+
step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })),
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const content: ToolLocaleContent<DamageFormulaLabUI> = {
|
|
67
|
+
slug,
|
|
68
|
+
title,
|
|
69
|
+
description,
|
|
70
|
+
ui: {
|
|
71
|
+
onboarding: 'Inserisci la formula attualmente in uso, affiancala a un alternativa e regola i parametri di combattimento.',
|
|
72
|
+
localNote: 'Modello privato. Formule e dati rimangono all interno di questo browser.',
|
|
73
|
+
formulaDeck: 'Stanza delle formule',
|
|
74
|
+
formulaALabel: 'Formula A (Modello attuale)',
|
|
75
|
+
formulaBLabel: 'Formula B (Alternativa)',
|
|
76
|
+
formulaHint: 'Variabili: attack, defense, level, power, resistance, flat, criticalChance, criticalMultiplier',
|
|
77
|
+
formulaFunctions: 'Funzioni sicure: min, max, clamp, abs, sqrt, pow, floor, round, ceil',
|
|
78
|
+
presetLinear: 'Protezione lineare',
|
|
79
|
+
presetRatio: 'Armatura a rapporto',
|
|
80
|
+
presetLevel: 'Scalabilità per livello',
|
|
81
|
+
combatInputs: 'Stato di combattimento',
|
|
82
|
+
attackLabel: 'Attacco',
|
|
83
|
+
defenseLabel: 'Difesa',
|
|
84
|
+
levelLabel: 'Livello',
|
|
85
|
+
powerLabel: 'Coefficiente di potenza',
|
|
86
|
+
resistanceLabel: 'Resistenza (%)',
|
|
87
|
+
flatLabel: 'Modificatore piatto',
|
|
88
|
+
criticalChanceLabel: 'Probabilità di critico (%)',
|
|
89
|
+
criticalMultiplierLabel: 'Moltiplicatore critico',
|
|
90
|
+
healthLabel: 'Salute del bersaglio',
|
|
91
|
+
cadenceLabel: 'Attacchi al secondo',
|
|
92
|
+
roundingLabel: 'Arrotondamento danno',
|
|
93
|
+
roundingNone: 'Conserva decimali',
|
|
94
|
+
roundingFloor: 'Arrotonda per difetto (Floor)',
|
|
95
|
+
roundingRound: 'Intero più vicino',
|
|
96
|
+
roundingCeil: 'Arrotonda per eccesso (Ceil)',
|
|
97
|
+
orderLabel: 'Ordine dei modificatori',
|
|
98
|
+
resistanceFirst: 'Resistenza poi piatto',
|
|
99
|
+
flatFirst: 'Piatto poi resistenza',
|
|
100
|
+
runLabel: 'Confronto di impatto in tempo reale',
|
|
101
|
+
resultDamage: 'Danno previsto',
|
|
102
|
+
resultHits: 'Colpi per sconfiggere',
|
|
103
|
+
resultTtk: 'Time to Kill (TTK)',
|
|
104
|
+
resultDifference: 'Differenza di danno',
|
|
105
|
+
formulaAName: 'Attuale',
|
|
106
|
+
formulaBName: 'Alternativa',
|
|
107
|
+
curveTitle: 'Traiettoria di attacco',
|
|
108
|
+
curveCaption: 'L attacco varia dalla metà al doppio del valore attuale mentre la difesa rimane fissa.',
|
|
109
|
+
heatmapTitle: 'Mappa di calore di pressione',
|
|
110
|
+
heatmapCaption: 'Mostra il danno previsto della Formula A su combinazioni di attacco e difesa.',
|
|
111
|
+
attackAxis: 'L attacco aumenta verso destra',
|
|
112
|
+
defenseAxis: 'La difesa aumenta verso il basso',
|
|
113
|
+
scenariosTitle: 'Profili di combattimento',
|
|
114
|
+
scenarioSkirmisher: 'Assaltatore',
|
|
115
|
+
scenarioGuardian: 'Guardiano',
|
|
116
|
+
scenarioBoss: 'Boss',
|
|
117
|
+
scenarioCustom: 'Configurazione attuale',
|
|
118
|
+
diagnosticsTitle: 'Verifica soglie e avvisi',
|
|
119
|
+
statusBalanced: 'Nessuna anomalia matematica rilevata in questo intervallo di test.',
|
|
120
|
+
exportTitle: 'Esporta esperimento',
|
|
121
|
+
copyLink: 'Copia link di condivisione',
|
|
122
|
+
exportCsv: 'Scarica CSV',
|
|
123
|
+
exportJson: 'Scarica JSON',
|
|
124
|
+
importJson: 'Importa JSON',
|
|
125
|
+
exportPng: 'Scarica PNG grafico',
|
|
126
|
+
reset: 'Ripristina modello',
|
|
127
|
+
privacyDisclosure: 'Il link di condivisione salva la configurazione nell URL senza inviare dati a server esterni.',
|
|
128
|
+
limitationDisclosure: 'Il danno critico previsto è una media e non una simulazione casuale.',
|
|
129
|
+
importError: 'Il file selezionato non è una configurazione valida.',
|
|
130
|
+
copiedStatus: 'Link copiato negli appunti.',
|
|
131
|
+
},
|
|
132
|
+
seo: [
|
|
133
|
+
{
|
|
134
|
+
type: 'title',
|
|
135
|
+
level: 2,
|
|
136
|
+
text: 'Testare le formule di danno prima di integrarle nel motore di gioco',
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
type: 'paragraph',
|
|
140
|
+
html: 'Una formula di danno può sembrare corretta su valori medi ma fallire agli estremi della progressione. Questo laboratorio permette di identificare soglie e anomalie prima della stesura del codice.',
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
type: 'title',
|
|
144
|
+
level: 2,
|
|
145
|
+
text: 'Linguaggio di espressione sicuro e delimitato',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
type: 'paragraph',
|
|
149
|
+
html: 'Il campo della formula accetta esclusivamente variabili e funzioni matematiche predefinite senza eseguire codice arbitrario.',
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
type: 'table',
|
|
153
|
+
headers: ['Metrica', 'Calcolo effettuato', 'Domanda di design'],
|
|
154
|
+
rows: [
|
|
155
|
+
['Danno previsto', 'Formula base inclusiva di fattore critico e ordine di resistenza', 'La regola risponde in modo coerente su personaggi deboli e forti?'],
|
|
156
|
+
['Colpi per sconfiggere', 'Salute divisa per il danno arrotondato', 'Un singolo punto di statistica elimina un intero colpo necessario?'],
|
|
157
|
+
['Time to Kill (TTK)', 'Intervallo tra i colpi diviso per la cadenza di attacco', 'La frequenza crea il ritmo di combattimento desiderato?'],
|
|
158
|
+
['Mappa di calore', 'Campionamento della Formula A su attacco e difesa', 'Vi sono zone morte o salti improvvisi?'],
|
|
159
|
+
],
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
type: 'title',
|
|
163
|
+
level: 2,
|
|
164
|
+
text: 'Separare l aritmetica dal giudizio sul bilanciamento',
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
type: 'paragraph',
|
|
168
|
+
html: 'Un grafico regolare non è una prova automatica di divertimento. Utilizza il laboratorio per individuare le domande da verificare nelle sessioni di playtest.',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
type: 'tip',
|
|
172
|
+
title: 'Esamina sempre sia il danno che i colpi necessari',
|
|
173
|
+
html: 'Una piccola variazione di danno può superare una soglia di salute ed eliminare un intero colpo. Confronta sempre il danno con il TTK.',
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
faq,
|
|
177
|
+
bibliographyTitle: 'Riferimenti per il calcolo del danno nei videogiochi',
|
|
178
|
+
bibliography: bibliographyEntries,
|
|
179
|
+
howTo,
|
|
180
|
+
schemas: [softwareApplication, faqPage, howToSchema],
|
|
181
|
+
};
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type { FAQPage, HowTo, SoftwareApplication, WithContext } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { DamageFormulaLabUI } from '../ui';
|
|
4
|
+
import { bibliographyEntries } from '../bibliography';
|
|
5
|
+
|
|
6
|
+
const slug = 'game-damage-formula-calculator-ttk';
|
|
7
|
+
const title = 'ゲームダメージ計算・TTKシミュレーター';
|
|
8
|
+
const description = '安全な計算式でゲームのダメージ・撃破所要時間(TTK)を比較。リアルタイム曲線、ヒートマップ、端数処理、クリティカルの影響を分析。';
|
|
9
|
+
|
|
10
|
+
const faq = [
|
|
11
|
+
{
|
|
12
|
+
question: 'ダメージ計算・TTKシミュレーターとは何ですか?',
|
|
13
|
+
answer: '同じ戦闘ステータスに対して2つのダメージ計算式を安全に比較・評価するツールです。ダメージ曲線、撃破に必要な攻撃回数、TTK、端数処理、耐性の適用順序をJavaScriptの直接実行なしで確認できます。',
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
question: 'どのような変数や関数が使用できますか?',
|
|
17
|
+
answer: '使用可能な変数は attack, defense, level, power, resistance, flat, criticalChance, criticalMultiplier です。安全な関数として min, max, clamp, abs, sqrt, pow, floor, round, ceil が用意されています。',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
question: '撃破時間(TTK)はどのように計算されますか?',
|
|
21
|
+
answer: '撃破攻撃回数は対象HPを端数処理後の予測ダメージで割り、切り上げた値です。TTKは最初の攻撃から最後の攻撃までの時間間隔を表すため、(必要攻撃回数 - 1) / 秒間攻撃回数 で算出されます。1撃で倒せる場合のTTKは0秒です。',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
question: '耐性の適用順序で結果が変わるのはなぜですか?',
|
|
25
|
+
answer: '固定加減算をパーセント耐性の前に適用すると、固定値自体も耐性によって減少します。耐性を先に適用すると、後の固定加減算は影響を受けません。ゲームエンジンや設計思想に合わせて両方の計算順序を切り替えられます。',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
question: '曲線が滑らかであればゲームバランスは良好と言えますか?',
|
|
29
|
+
answer: 'いいえ。曲線はダメージ0領域や急激な変化点を可視化しますが、実際のバランスはゲームの目的、プレイヤーの選択、体験の設計に依存します。数値上の挙動を示すものであり、絶対的な評価を与えるものではありません。',
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
const howTo = [
|
|
34
|
+
{ name: '2つの計算式を選択', text: '線形・比率・レベル補正などのプリセットから選択するか、独自の計算式A・Bを入力します。' },
|
|
35
|
+
{ name: '戦闘ステータスを設定', text: '攻撃力、防御力、レベル、威力係数、耐性、固定値、クリティカル率・倍率、対象HP、攻撃速度を設定します。' },
|
|
36
|
+
{ name: 'エンジンのルールを指定', text: 'ダメージの端数処理方法と、耐性と固定値の適用順序を選択します。' },
|
|
37
|
+
{ name: '曲線と変化点を分析', text: '攻撃力推移の曲線、防御ヒートマップ、必要攻撃回数、TTK、警告診断を確認します。' },
|
|
38
|
+
{ name: '設定を保存・共有', text: '共有用URLをコピーするか、JSON設定、CSVデータ、グラフ画像(PNG)をダウンロードします。' },
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
const softwareApplication: WithContext<SoftwareApplication> = {
|
|
42
|
+
'@context': 'https://schema.org',
|
|
43
|
+
'@type': 'SoftwareApplication',
|
|
44
|
+
name: title,
|
|
45
|
+
applicationCategory: 'DeveloperApplication',
|
|
46
|
+
operatingSystem: 'Any',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const faqPage: WithContext<FAQPage> = {
|
|
50
|
+
'@context': 'https://schema.org',
|
|
51
|
+
'@type': 'FAQPage',
|
|
52
|
+
mainEntity: faq.map((item) => ({
|
|
53
|
+
'@type': 'Question',
|
|
54
|
+
name: item.question,
|
|
55
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
56
|
+
})),
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const howToSchema: WithContext<HowTo> = {
|
|
60
|
+
'@context': 'https://schema.org',
|
|
61
|
+
'@type': 'HowTo',
|
|
62
|
+
name: title,
|
|
63
|
+
step: howTo.map((step) => ({ '@type': 'HowToStep', name: step.name, text: step.text })),
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const content: ToolLocaleContent<DamageFormulaLabUI> = {
|
|
67
|
+
slug,
|
|
68
|
+
title,
|
|
69
|
+
description,
|
|
70
|
+
ui: {
|
|
71
|
+
onboarding: '現在のダメージ計算式と代替案を入力し、戦闘ステータスを調整して極端なステータス帯での挙動を検証します。',
|
|
72
|
+
privacyNote: 'ローカル専用設計。計算式や設定はブラウザ内のみで処理されます。',
|
|
73
|
+
loadSprite: '計算式入力エリア',
|
|
74
|
+
formulaDeck: '計算式デッキ',
|
|
75
|
+
formulaALabel: '計算式A (現行モデル)',
|
|
76
|
+
formulaBLabel: '計算式B (比較案)',
|
|
77
|
+
formulaHint: '変数: attack, defense, level, power, resistance, flat, criticalChance, criticalMultiplier',
|
|
78
|
+
formulaFunctions: '安全関数: min, max, clamp, abs, sqrt, pow, floor, round, ceil',
|
|
79
|
+
presetLinear: '線形軽減',
|
|
80
|
+
presetRatio: '比率防御',
|
|
81
|
+
presetLevel: 'レベル補正',
|
|
82
|
+
combatInputs: '戦闘ステータス設定',
|
|
83
|
+
attackLabel: '攻撃力 (Attack)',
|
|
84
|
+
defenseLabel: '防御力 (Defense)',
|
|
85
|
+
levelLabel: 'レベル (Level)',
|
|
86
|
+
powerLabel: '威力係数 (Power)',
|
|
87
|
+
resistanceLabel: '耐性パーセント (Resistance %)',
|
|
88
|
+
flatLabel: '固定加減算 (Flat)',
|
|
89
|
+
criticalChanceLabel: 'クリティカル率 (%)',
|
|
90
|
+
criticalMultiplierLabel: 'クリティカル倍率',
|
|
91
|
+
healthLabel: '対象HP (Health)',
|
|
92
|
+
cadenceLabel: '秒間攻撃回数 (APS)',
|
|
93
|
+
roundingLabel: 'ダメージ端数処理',
|
|
94
|
+
roundingNone: '小数点を維持',
|
|
95
|
+
roundingFloor: '切り捨て (Floor)',
|
|
96
|
+
roundingRound: '四捨五入 (Round)',
|
|
97
|
+
roundingCeil: '切り上げ (Ceil)',
|
|
98
|
+
orderLabel: '計算適用順序',
|
|
99
|
+
resistanceFirst: '耐性 % → 固定値',
|
|
100
|
+
flatFirst: '固定値 → 耐性 %',
|
|
101
|
+
runLabel: 'リアルタイム影響比較',
|
|
102
|
+
resultDamage: '予測ダメージ',
|
|
103
|
+
resultHits: '撃破必要攻撃回数',
|
|
104
|
+
resultTtk: '撃破所要時間 (TTK)',
|
|
105
|
+
resultDifference: 'ダメージ差分',
|
|
106
|
+
formulaAName: '現行案',
|
|
107
|
+
formulaBName: '比較案',
|
|
108
|
+
curveTitle: '攻撃力推移グラフ',
|
|
109
|
+
curveCaption: '防御力を固定したまま、攻撃力を現在の半分の値から2倍の値までスウィープ検証します。',
|
|
110
|
+
heatmapTitle: '攻撃・防御ヒートマップ',
|
|
111
|
+
heatmapCaption: '攻撃力と防御力の各組み合わせにおける計算式Aの予測ダメージを表示します。',
|
|
112
|
+
attackAxis: '右に行くほど攻撃力上昇',
|
|
113
|
+
defenseAxis: '下に行くほど防御力上昇',
|
|
114
|
+
scenariosTitle: '戦闘ターゲットプリセット',
|
|
115
|
+
scenarioSkirmisher: '一般エネミー',
|
|
116
|
+
scenarioGuardian: '重装エネミー',
|
|
117
|
+
scenarioBoss: 'ボスエネミー',
|
|
118
|
+
scenarioCustom: 'カスタム設定',
|
|
119
|
+
diagnosticsTitle: 'ブレイクポイント診断',
|
|
120
|
+
statusBalanced: '現在の検証範囲内で異常な数値の飛躍は検出されませんでした。',
|
|
121
|
+
exportTitle: '設定・データの出力',
|
|
122
|
+
copyLink: '共有リンクをコピー',
|
|
123
|
+
exportCsv: 'CSVダウンロード',
|
|
124
|
+
exportJson: 'JSONダウンロード',
|
|
125
|
+
importJson: 'JSONインポート',
|
|
126
|
+
exportPng: 'グラフ画像(PNG)ダウンロード',
|
|
127
|
+
reset: 'モデルのリセット',
|
|
128
|
+
privacyDisclosure: '共有リンクはURLハッシュ内に設定を保持し、外部サーバーへ送信されることはありません。',
|
|
129
|
+
limitationDisclosure: 'クリティカルダメージは平均期待値であり、ランダム試行のシミュレーションではありません。',
|
|
130
|
+
importError: '選択されたファイルは有効な設定データではありません。',
|
|
131
|
+
copiedStatus: '共有リンクをクリップボードにコピーしました。',
|
|
132
|
+
},
|
|
133
|
+
seo: [
|
|
134
|
+
{
|
|
135
|
+
type: 'title',
|
|
136
|
+
level: 2,
|
|
137
|
+
text: 'ゲームエンジンへ組み込む前にダメージ計算式を検証',
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
type: 'paragraph',
|
|
141
|
+
html: '特定の値で問題なく見えても、ステータスが上昇した際にダメージ0や極端な数値へ崩壊することがあります。本ツールでは2つの計算式を同時にスウィープ検証できます。',
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
type: 'title',
|
|
145
|
+
level: 2,
|
|
146
|
+
text: '安全で制限された数式評価言語',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
type: 'paragraph',
|
|
150
|
+
html: '入力フィールドは定義された変数と数学関数のみを受け付け、任意のJavaScriptコードを実行することなく安全に計算を行います。',
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
type: 'table',
|
|
154
|
+
headers: ['評価指標', '計算内容', '設計上の検討事項'],
|
|
155
|
+
rows: [
|
|
156
|
+
['予測ダメージ', 'クリティカル期待値・耐性・端数処理を含めた基本ダメージ', 'ステータス成長に対して意図通りのダメージが伸びているか?'],
|
|
157
|
+
['必要攻撃回数', '対象HPを端数処理後ダメージで割り切り上げ', '1ポイントのステータス上昇が必要攻撃回数を劇的に減らしていないか?'],
|
|
158
|
+
['撃破所要時間 (TTK)', '攻撃回数間隔を秒間攻撃速度で除算', '攻撃速度が意図した戦闘テンポを生み出しているか?'],
|
|
159
|
+
['ヒートマップ', '攻撃力と防御力の組み合わせによるダメージ分布', '不自然なダメージ停滞帯や急激な閾値が存在しないか?'],
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
type: 'title',
|
|
164
|
+
level: 2,
|
|
165
|
+
text: '数値計算の検証とバランス調整の分離',
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
type: 'paragraph',
|
|
169
|
+
html: '綺麗なグラフがそのままゲームの面白さを保証するわけではありません。試遊テストで確認すべきポイントを発見するためのツールとしてご活用ください。',
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
type: 'tip',
|
|
173
|
+
title: 'ダメージ数値と撃破攻撃回数の両方を確認する',
|
|
174
|
+
html: '僅かなダメージの変化であっても、HPの閾値を跨ぐことで必要な攻撃回数が1回減る場合があります。常にTTKと必要攻撃回数をセットで分析してください。',
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
faq,
|
|
178
|
+
bibliographyTitle: 'ダメージ設計・数値計算の参考資料',
|
|
179
|
+
bibliography: bibliographyEntries,
|
|
180
|
+
howTo,
|
|
181
|
+
schemas: [softwareApplication, faqPage, howToSchema],
|
|
182
|
+
};
|