improvements

This commit is contained in:
Michal Vrba
2026-08-29 09:18:52 +02:00
parent 08a56604b0
commit 8fcca27cf8
20 changed files with 153 additions and 29 deletions
+3
View File
@@ -16,6 +16,9 @@ public sealed class AudioService(IJSRuntime js)
public async ValueTask PlaySfxAsync(string? source) => public async ValueTask PlaySfxAsync(string? source) =>
await js.InvokeVoidAsync("nullDepth.audio.playSfx", source); await js.InvokeVoidAsync("nullDepth.audio.playSfx", source);
public async ValueTask SetHeartbeatBpmAsync(int bpm) =>
await js.InvokeVoidAsync("nullDepth.audio.setHeartbeatBpm", bpm);
public async ValueTask StopAsync() => public async ValueTask StopAsync() =>
await js.InvokeVoidAsync("nullDepth.audio.stopAll"); await js.InvokeVoidAsync("nullDepth.audio.stopAll");
} }
+4
View File
@@ -17,6 +17,7 @@ public sealed class ItemDefinition
public string DescriptionKey { get; set; } = ""; public string DescriptionKey { get; set; } = "";
public string? DetailedKey { get; set; } public string? DetailedKey { get; set; }
public string Category { get; set; } = "equipment"; public string Category { get; set; } = "equipment";
public string? Image { get; set; }
} }
public sealed class ArchiveDefinition public sealed class ArchiveDefinition
@@ -24,6 +25,9 @@ public sealed class ArchiveDefinition
public string Id { get; set; } = ""; public string Id { get; set; } = "";
public string TitleKey { get; set; } = ""; public string TitleKey { get; set; } = "";
public string ContentKey { get; set; } = ""; public string ContentKey { get; set; } = "";
public string? Image { get; set; }
public string? AuthorKey { get; set; }
public string? ClassificationKey { get; set; }
} }
public sealed class RoomDefinition public sealed class RoomDefinition
+55 -8
View File
@@ -50,7 +50,7 @@
} }
else if (_screen == Screen.Briefing) else if (_screen == Screen.Briefing)
{ {
<section class="briefing-screen screen-image" style="background-image:url('assets/images/title/title_null_depth.webp')"> <section class="briefing-screen screen-image" style="background-image:url('assets/images/briefing/briefing_arrival.jpg')">
<div class="vignette"></div> <div class="vignette"></div>
<article class="terminal-card briefing-card"> <article class="terminal-card briefing-card">
<p class="eyebrow">@Game.T("briefing.header")</p> <p class="eyebrow">@Game.T("briefing.header")</p>
@@ -298,8 +298,17 @@
if (selectedItem is not null) if (selectedItem is not null)
{ {
<div class="item-inspect-box"> <div class="item-inspect-box">
<strong>@Game.T("inventory.inspectPrompt")</strong> <div class="item-inspect-layout">
<p style="margin:.4rem 0 0;">@(selectedItem.DetailedKey is not null ? Game.T(selectedItem.DetailedKey) : Game.T(selectedItem.DescriptionKey))</p> @if (!string.IsNullOrWhiteSpace(selectedItem.Image))
{
<div class="item-inspect-image-wrap">
<img src="@selectedItem.Image" alt="@Game.T(selectedItem.NameKey)" class="item-inspect-image" />
</div>
}
<div class="item-inspect-info">
<span class="item-category-badge">@selectedItem.Category.ToUpperInvariant() // SPECIFICATION</span>
<strong>@Game.T(selectedItem.NameKey)</strong>
<p style="margin:.3rem 0 0;">@(selectedItem.DetailedKey is not null ? Game.T(selectedItem.DetailedKey) : Game.T(selectedItem.DescriptionKey))</p>
@if (selectedItem.Id == "diagnostic_scanner") @if (selectedItem.Id == "diagnostic_scanner")
{ {
<div class="inspect-actions"> <div class="inspect-actions">
@@ -307,6 +316,8 @@
</div> </div>
} }
</div> </div>
</div>
</div>
} }
} }
} }
@@ -334,7 +345,25 @@
{ {
<details> <details>
<summary>@Game.T(entry.TitleKey)</summary> <summary>@Game.T(entry.TitleKey)</summary>
<div class="archive-body">
@if (!string.IsNullOrWhiteSpace(entry.Image))
{
<div class="archive-dossier-wrap">
<img src="@entry.Image" alt="Personnel Dossier" class="archive-dossier-portrait" />
<div class="archive-dossier-meta">
@if (!string.IsNullOrWhiteSpace(entry.ClassificationKey))
{
<span class="dossier-badge">@Game.T(entry.ClassificationKey)</span>
}
@if (!string.IsNullOrWhiteSpace(entry.AuthorKey))
{
<strong class="dossier-author">@Game.T(entry.AuthorKey)</strong>
}
</div>
</div>
}
<p class="terminal-copy">@Game.T(entry.ContentKey)</p> <p class="terminal-copy">@Game.T(entry.ContentKey)</p>
</div>
</details> </details>
} }
} }
@@ -500,6 +529,7 @@
await Game.NewGameAsync(); await Game.NewGameAsync();
_screen = Screen.Briefing; _screen = Screen.Briefing;
_notice = null; _notice = null;
await Audio.PlayAmbientAsync("assets/audio/amb_facility.mp3");
} }
private async Task ContinueGame() private async Task ContinueGame()
@@ -511,12 +541,14 @@
_ending = Game.State.CompletedEnding; _ending = Game.State.CompletedEnding;
_screen = _ending is null ? Screen.Game : Screen.Ending; _screen = _ending is null ? Screen.Game : Screen.Ending;
await Audio.PlayAmbientAsync(Game.CurrentRoom.Ambient); await Audio.PlayAmbientAsync(Game.CurrentRoom.Ambient);
await Audio.SetHeartbeatBpmAsync(Game.CurrentBpm);
} }
private async Task BeginPlay() private async Task BeginPlay()
{ {
_screen = Screen.Game; _screen = Screen.Game;
await Audio.PlayAmbientAsync(Game.CurrentRoom.Ambient); await Audio.PlayAmbientAsync(Game.CurrentRoom.Ambient);
await Audio.SetHeartbeatBpmAsync(Game.CurrentBpm);
} }
private async Task Move(string direction) private async Task Move(string direction)
@@ -530,6 +562,7 @@
var result = await Game.MoveAsync(direction); var result = await Game.MoveAsync(direction);
if (result is not null) _notice = result; if (result is not null) _notice = result;
if (result == "") { _notice = null; await Audio.PlayAmbientAsync(Game.CurrentRoom.Ambient); } if (result == "") { _notice = null; await Audio.PlayAmbientAsync(Game.CurrentRoom.Ambient); }
await Audio.SetHeartbeatBpmAsync(Game.CurrentBpm);
await Task.Delay(260); await Task.Delay(260);
_isTransitioning = false; _isTransitioning = false;
} }
@@ -561,6 +594,10 @@
_choiceIndex = 0; _choiceIndex = 0;
_selectedBreaker = 0; _selectedBreaker = 0;
_notice = null; _notice = null;
if (interaction.Id is "ai_interrogation" or "final_diagnostic")
{
_ = Audio.PlaySfxAsync("assets/audio/sfx_core_whisper.wav");
}
} }
private void SelectInteraction(InteractionDefinition interaction) => OpenInteraction(interaction); private void SelectInteraction(InteractionDefinition interaction) => OpenInteraction(interaction);
@@ -578,7 +615,7 @@
} }
if (hs.TelemetryKey is not null) if (hs.TelemetryKey is not null)
{ {
await Audio.PlaySfxAsync("assets/audio/sfx_ui_confirm.mp3"); await Audio.PlaySfxAsync("assets/audio/sfx_lidar_scan.wav");
_notice = Game.T(hs.TelemetryKey); _notice = Game.T(hs.TelemetryKey);
} }
} }
@@ -586,7 +623,7 @@
private async Task ToggleScanMode() private async Task ToggleScanMode()
{ {
_scanMode = !_scanMode; _scanMode = !_scanMode;
await Audio.PlaySfxAsync("assets/audio/sfx_ui_confirm.mp3"); await Audio.PlaySfxAsync("assets/audio/sfx_lidar_scan.wav");
} }
private async Task ResolveInteraction() private async Task ResolveInteraction()
@@ -598,6 +635,7 @@
_interaction = null; _interaction = null;
if (resolved.SetFlags.Contains("power_restored") || resolved.Sound?.Contains("alarm") == true || resolved.Sound?.Contains("disturbance") == true) if (resolved.SetFlags.Contains("power_restored") || resolved.Sound?.Contains("alarm") == true || resolved.Sound?.Contains("disturbance") == true)
_ = TriggerSystemFlashAsync(); _ = TriggerSystemFlashAsync();
await Audio.SetHeartbeatBpmAsync(Game.CurrentBpm);
await Task.Delay(180); await Task.Delay(180);
_notice = Game.T(resolved.ContentKey); _notice = Game.T(resolved.ContentKey);
} }
@@ -605,19 +643,27 @@
private async Task ResolveChoice(ChoiceDefinition choice) private async Task ResolveChoice(ChoiceDefinition choice)
{ {
await Game.ApplyChoiceAsync(choice); await Game.ApplyChoiceAsync(choice);
if (_interaction?.Id == "power_routing")
{
await Audio.PlaySfxAsync("assets/audio/sfx_breaker_heavy.wav");
}
else
{
await Audio.PlaySfxAsync(choice.Sound); await Audio.PlaySfxAsync(choice.Sound);
}
_interaction = null; _interaction = null;
if (choice.Sound?.Contains("alarm") == true || choice.Sound?.Contains("disturbance") == true) if (choice.Sound?.Contains("alarm") == true || choice.Sound?.Contains("disturbance") == true)
_ = TriggerSystemFlashAsync(); _ = TriggerSystemFlashAsync();
if (choice.Death) { _screen = Screen.Death; return; } if (choice.Death) { await Audio.SetHeartbeatBpmAsync(0); _screen = Screen.Death; return; }
if (!string.IsNullOrWhiteSpace(choice.Ending)) { _ending = choice.Ending; _screen = Screen.Ending; return; } if (!string.IsNullOrWhiteSpace(choice.Ending)) { await Audio.SetHeartbeatBpmAsync(0); _ending = choice.Ending; _screen = Screen.Ending; return; }
await Audio.SetHeartbeatBpmAsync(Game.CurrentBpm);
await Task.Delay(180); await Task.Delay(180);
_notice = choice.ResultKey is null ? null : Game.T(choice.ResultKey); _notice = choice.ResultKey is null ? null : Game.T(choice.ResultKey);
} }
private async Task TriggerScan() private async Task TriggerScan()
{ {
await Audio.PlaySfxAsync("assets/audio/sfx_ui_confirm.mp3"); await Audio.PlaySfxAsync("assets/audio/sfx_lidar_scan.wav");
_notice = Game.ScanCurrentRoom(); _notice = Game.ScanCurrentRoom();
} }
@@ -650,6 +696,7 @@
_screen = Screen.Title; _screen = Screen.Title;
_menuIndex = 0; _menuIndex = 0;
_titleNotice = null; _titleNotice = null;
await Audio.SetHeartbeatBpmAsync(0);
await Audio.PlayAmbientAsync("assets/audio/music_title_vocal.mp3"); await Audio.PlayAmbientAsync("assets/audio/music_title_vocal.mp3");
} }
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 822 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 836 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 892 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 KiB

+22 -3
View File
@@ -79,16 +79,35 @@ kbd { color:var(--cyan); background:none; padding:0; }
.map-cell.visited { color:var(--cyan); background:rgba(65,213,240,.06); border-color:var(--line); } .map-cell.visited { color:var(--cyan); background:rgba(65,213,240,.06); border-color:var(--line); }
.map-cell.current { color:#021014; background:var(--cyan); box-shadow:0 0 24px rgba(66,216,244,.4); font-weight:bold; } .map-cell.current { color:#021014; background:var(--cyan); box-shadow:0 0 24px rgba(66,216,244,.4); font-weight:bold; }
.inventory-card { width:min(52rem,94vw); }
.inventory-card ul { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.65rem; list-style:none; margin:1.5rem 0 0; padding:0; } .inventory-card ul { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.65rem; list-style:none; margin:1.5rem 0 0; padding:0; }
.inventory-card li { padding:1rem; border:1px solid var(--line); cursor:pointer; transition:.15s ease; background:rgba(0,5,8,.4); } .inventory-card li { padding:1rem; border:1px solid var(--line); cursor:pointer; transition:.15s ease; background:rgba(0,5,8,.4); }
.inventory-card li:hover, .inventory-card li.selected-item { border-color:var(--cyan); background:rgba(66,216,244,.06); } .inventory-card li:hover, .inventory-card li.selected-item { border-color:var(--cyan); background:rgba(66,216,244,.06); }
.inventory-card li small { display:block; color:var(--muted); font-size:.58rem; letter-spacing:.16em; } .inventory-card li small { display:block; color:var(--muted); font-size:.58rem; letter-spacing:.16em; }
.inventory-card li strong { display:block; margin:.3rem 0; color:var(--cyan); font-weight:500; letter-spacing:.06em; } .inventory-card li strong { display:block; margin:.3rem 0; color:var(--cyan); font-weight:500; letter-spacing:.06em; }
.inventory-card li p { margin:.25rem 0 0; color:#b8c8cb; font-size:.78rem; line-height:1.5; } .inventory-card li p { margin:.25rem 0 0; color:#b8c8cb; font-size:.78rem; line-height:1.5; }
.item-inspect-box { margin-top:1.2rem; padding:1.2rem; border:1px solid var(--cyan-strong); background:rgba(3,15,20,.85); font-family:'IBM Plex Mono',monospace; font-size:.76rem; color:#d8f4f8; line-height:1.6; }
.item-inspect-box .inspect-actions { margin-top:1rem; display:flex; gap:.6rem; }
.archive-list { display:flex; flex-direction:column; gap:.55rem; margin-top:1.5rem; }.archive-list details { border:1px solid var(--line); background:rgba(0,6,8,.45); }.archive-list summary { padding:1rem; color:var(--cyan); cursor:pointer; letter-spacing:.07em; }.archive-list details p { margin:0; padding:0 1rem 1rem; } .item-inspect-box { margin-top:1.2rem; padding:1.2rem; border:1px solid var(--cyan-strong); background:rgba(3,15,20,.9); font-family:'IBM Plex Mono',monospace; font-size:.76rem; color:#d8f4f8; line-height:1.6; }
.item-inspect-layout { display:grid; grid-template-columns:130px 1fr; gap:1.2rem; align-items:start; }
.item-inspect-image-wrap { width:130px; height:130px; border:1px solid rgba(66,216,244,.4); overflow:hidden; background:#01070a; box-shadow:0 0 16px rgba(66,216,244,.15); }
.item-inspect-image { width:100%; height:100%; object-fit:cover; display:block; transition:transform .3s ease; }
.item-inspect-image:hover { transform:scale(1.05); }
.item-inspect-info { display:flex; flex-direction:column; gap:.35rem; }
.item-category-badge { display:inline-block; font-size:.58rem; color:var(--cyan); letter-spacing:.15em; border-bottom:1px solid rgba(66,216,244,.3); padding-bottom:.2rem; width:fit-content; }
.item-inspect-box .inspect-actions { margin-top:.8rem; display:flex; gap:.6rem; }
.archive-card { width:min(52rem,94vw); }
.archive-list { display:flex; flex-direction:column; gap:.7rem; margin-top:1.5rem; }
.archive-list details { border:1px solid var(--line); background:rgba(0,6,8,.6); transition:border-color .2s ease; }
.archive-list details[open] { border-color:var(--cyan); background:rgba(2,12,18,.75); }
.archive-list summary { padding:1rem; color:var(--cyan); cursor:pointer; letter-spacing:.07em; font-weight:500; }
.archive-body { padding:0 1.2rem 1.2rem; }
.archive-dossier-wrap { display:flex; gap:1.2rem; align-items:center; margin-bottom:1rem; padding:.8rem 1rem; border:1px solid rgba(158,239,255,.15); background:rgba(1,8,11,.7); }
.archive-dossier-portrait { width:72px; height:72px; border-radius:4px; border:1px solid var(--cyan); object-fit:cover; box-shadow:0 0 12px rgba(66,216,244,.25); }
.archive-dossier-meta { display:flex; flex-direction:column; gap:.25rem; }
.dossier-badge { font-size:.6rem; color:var(--cyan); letter-spacing:.14em; font-family:'IBM Plex Mono',monospace; }
.dossier-author { color:#cad9dc; font-size:.72rem; font-family:'IBM Plex Mono',monospace; }
.pause-card, .settings-card { display:flex; flex-direction:column; gap:.75rem; width:min(29rem,92vw); }.settings-card label { margin-top:.5rem; color:var(--muted); font-size:.76rem; letter-spacing:.09em; }.segmented-control { display:grid; grid-template-columns:1fr 1fr; gap:.4rem; }.settings-card input { accent-color:var(--cyan-strong); } .pause-card, .settings-card { display:flex; flex-direction:column; gap:.75rem; width:min(29rem,92vw); }.settings-card label { margin-top:.5rem; color:var(--muted); font-size:.76rem; letter-spacing:.09em; }.segmented-control { display:grid; grid-template-columns:1fr 1fr; gap:.4rem; }.settings-card input { accent-color:var(--cyan-strong); }
.setting-toggle.active { color:#031013; background:var(--cyan); border-color:var(--cyan); } .setting-toggle.active { color:#031013; background:var(--cyan); border-color:var(--cyan); }
.danger-action { color:#ff9da2; border-color:rgba(255,77,87,.55); }.danger-action:hover, .danger-action:focus-visible { color:white; background:#a51f29; border-color:#ff5e68; } .danger-action { color:#ff9da2; border-color:rgba(255,77,87,.55); }.danger-action:hover, .danger-action:focus-visible { color:white; background:#a51f29; border-color:#ff5e68; }
+15 -11
View File
@@ -8,38 +8,42 @@
"nameKey": "item.contractor_credential.name", "nameKey": "item.contractor_credential.name",
"descriptionKey": "item.contractor_credential.description", "descriptionKey": "item.contractor_credential.description",
"detailedKey": "item.contractor_credential.detail", "detailedKey": "item.contractor_credential.detail",
"category": "credential" "category": "credential",
"image": "assets/images/items/item_contractor_credential.jpg"
}, },
{ {
"id": "diagnostic_scanner", "id": "diagnostic_scanner",
"nameKey": "item.diagnostic_scanner.name", "nameKey": "item.diagnostic_scanner.name",
"descriptionKey": "item.diagnostic_scanner.description", "descriptionKey": "item.diagnostic_scanner.description",
"detailedKey": "item.diagnostic_scanner.detail", "detailedKey": "item.diagnostic_scanner.detail",
"category": "tool" "category": "tool",
"image": "assets/images/items/item_diagnostic_scanner.jpg"
}, },
{ {
"id": "thermal_clamp", "id": "thermal_clamp",
"nameKey": "item.thermal_clamp.name", "nameKey": "item.thermal_clamp.name",
"descriptionKey": "item.thermal_clamp.description", "descriptionKey": "item.thermal_clamp.description",
"detailedKey": "item.thermal_clamp.detail", "detailedKey": "item.thermal_clamp.detail",
"category": "tool" "category": "tool",
"image": "assets/images/items/item_thermal_clamp.jpg"
}, },
{ {
"id": "manual_override", "id": "manual_override",
"nameKey": "item.manual_override.name", "nameKey": "item.manual_override.name",
"descriptionKey": "item.manual_override.description", "descriptionKey": "item.manual_override.description",
"detailedKey": "item.manual_override.detail", "detailedKey": "item.manual_override.detail",
"category": "module" "category": "module",
"image": "assets/images/items/item_manual_override.jpg"
} }
], ],
"archive": [ "archive": [
{ "id": "log_01", "titleKey": "archive.log_01.title", "contentKey": "log.01" }, { "id": "log_01", "titleKey": "archive.log_01.title", "contentKey": "log.01", "image": "assets/images/dossiers/dossier_dr_vance.jpg", "authorKey": "author.dr_vance", "classificationKey": "class.sub03" },
{ "id": "containment_record", "titleKey": "archive.containment_record.title", "contentKey": "terminal.operations" }, { "id": "containment_record", "titleKey": "archive.containment_record.title", "contentKey": "terminal.operations", "image": "assets/images/dossiers/dossier_marek_cale.jpg", "authorKey": "author.marek_cale", "classificationKey": "class.blackbox" },
{ "id": "incident_log", "titleKey": "archive.incident_log.title", "contentKey": "archive.incident_log.content" }, { "id": "incident_log", "titleKey": "archive.incident_log.title", "contentKey": "archive.incident_log.content", "image": "assets/images/dossiers/dossier_marek_cale.jpg", "authorKey": "author.marek_cale", "classificationKey": "class.security" },
{ "id": "log_02", "titleKey": "archive.log_02.title", "contentKey": "log.02" }, { "id": "log_02", "titleKey": "archive.log_02.title", "contentKey": "log.02", "image": "assets/images/dossiers/dossier_elena_rostova.jpg", "authorKey": "author.elena_rostova", "classificationKey": "class.engineering" },
{ "id": "engineer_notes", "titleKey": "archive.engineer_notes.title", "contentKey": "archive.engineer_notes.content" }, { "id": "engineer_notes", "titleKey": "archive.engineer_notes.title", "contentKey": "archive.engineer_notes.content", "image": "assets/images/dossiers/dossier_elena_rostova.jpg", "authorKey": "author.elena_rostova", "classificationKey": "class.engineering" },
{ "id": "log_03", "titleKey": "archive.log_03.title", "contentKey": "log.03" }, { "id": "log_03", "titleKey": "archive.log_03.title", "contentKey": "log.03", "image": "assets/images/dossiers/dossier_dr_vance.jpg", "authorKey": "author.dr_vance", "classificationKey": "class.neural" },
{ "id": "core_manifest", "titleKey": "archive.core_manifest.title", "contentKey": "archive.core_manifest.content" } { "id": "core_manifest", "titleKey": "archive.core_manifest.title", "contentKey": "archive.core_manifest.content", "image": "assets/images/dossiers/dossier_dr_vance.jpg", "authorKey": "author.dr_vance", "classificationKey": "class.architect" }
], ],
"rooms": [ "rooms": [
{ {
+27
View File
@@ -133,8 +133,35 @@
oscillator.stop(context.currentTime + config[1] + 0.03); oscillator.stop(context.currentTime + config[1] + 0.03);
}, },
heartbeatAudio: null,
setHeartbeatBpm(bpm) {
if (bpm < 105 || this.volume === 0) {
if (this.heartbeatAudio) {
this.heartbeatAudio.pause();
this.heartbeatAudio = null;
}
return;
}
if (!this.heartbeatAudio) {
this.heartbeatAudio = new Audio('assets/audio/sfx_heartbeat.wav');
this.heartbeatAudio.loop = true;
this.heartbeatAudio.volume = Math.min(0.7, (bpm - 90) / 40 * 0.7) * this.volume;
this.heartbeatAudio.play().catch(() => {});
} else {
const rate = Math.max(0.9, Math.min(2.0, bpm / 75.0));
this.heartbeatAudio.playbackRate = rate;
this.heartbeatAudio.volume = Math.min(0.7, (bpm - 90) / 40 * 0.7) * this.volume;
if (this.heartbeatAudio.paused) this.heartbeatAudio.play().catch(() => {});
}
},
stopAll() { stopAll() {
this.stopAmbient(); this.stopAmbient();
if (this.heartbeatAudio) {
this.heartbeatAudio.pause();
this.heartbeatAudio = null;
}
this.context?.suspend(); this.context?.suspend();
} }
}; };
@@ -44,6 +44,16 @@
"panel.breaker.balanced": "BALANCED SECURITY", "panel.breaker.balanced": "BALANCED SECURITY",
"panel.breaker.switch": "ENGAGE BREAKER", "panel.breaker.switch": "ENGAGE BREAKER",
"author.dr_vance": "Dr. Arthur Vance // Neural Research Director",
"author.elena_rostova": "Elena Rostova // Chief Cryogenic Engineer",
"author.marek_cale": "Commander Marek Cale // Chief Security Officer",
"class.sub03": "CLASSIFICATION: SUB-03 RESEARCH // CONFIDENTIAL",
"class.blackbox": "BLACK BOX // EMERGENCY PROTOCOL",
"class.security": "SECURITY JOURNAL // SECTOR LOG",
"class.engineering": "SERVICE DISPATCH // COOLING JUNCTION",
"class.neural": "NEURAL TELEMETRY // ARCHITECT PROJECT",
"class.architect": "SYSTEM MANIFEST // CORE SPECIFICATION",
"hotspot.loc_01.terminal": "CONTRACTOR TERMINAL", "hotspot.loc_01.terminal": "CONTRACTOR TERMINAL",
"hotspot.loc_01.gate": "PRESSURE GATE", "hotspot.loc_01.gate": "PRESSURE GATE",
"hotspot.loc_02.terminal": "PERSONNEL STATION", "hotspot.loc_02.terminal": "PERSONNEL STATION",
@@ -44,6 +44,16 @@
"panel.breaker.balanced": "KOMBINOVANÝ REŽIM", "panel.breaker.balanced": "KOMBINOVANÝ REŽIM",
"panel.breaker.switch": "ZOPNÚŤ ISTIČ", "panel.breaker.switch": "ZOPNÚŤ ISTIČ",
"author.dr_vance": "Dr. Arthur Vance // Riaditeľ výskumu",
"author.elena_rostova": "Ing. Elena Rostová // Hlavná inžinierka kryochladenia",
"author.marek_cale": "Veliteľ Marek Cale // Šéf internej bezpečnosti",
"class.sub03": "KLASIFIKÁCIA: VÝSKUM SUB-03 // DÔVERNÉ",
"class.blackbox": "ČIERNA SKRINKA // NÚDZOVÝ PROTOKOL",
"class.security": "BEZPEČNOSTNÝ DENNÍK // SEKTOROVÝ ZÁZNAM",
"class.engineering": "SERVISNÁ SPRÁVA // UZOL CHLADENIA",
"class.neural": "NEURÁLNA TELEMETRIA // PROJEKT ARCHITECT",
"class.architect": "SYSTÉMOVÝ MANIFEST // ZÁZNAM JADRA",
"hotspot.loc_01.terminal": "KONTRAKTORSKÝ TERMINÁL", "hotspot.loc_01.terminal": "KONTRAKTORSKÝ TERMINÁL",
"hotspot.loc_01.gate": "TLAKOVÁ BRÁNA", "hotspot.loc_01.gate": "TLAKOVÁ BRÁNA",
"hotspot.loc_02.terminal": "PERSONÁLNA STANICA", "hotspot.loc_02.terminal": "PERSONÁLNA STANICA",