feat: 实现游戏核心功能与前端界面
- 添加游戏核心系统:战斗、任务、日志、随机数生成等 - 实现前端主界面、HUD、底部导航和各类卡片组件 - 添加用户认证系统与游戏存档持久化 - 配置项目基础架构与开发环境 - 补充文档说明与Docker部署支持
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"name": "@tinywaste/content",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "tsup src/index.ts --format esm --dts --watch --out-dir dist",
|
||||
"build": "tsup src/index.ts --format esm --dts --clean --out-dir dist",
|
||||
"lint": "eslint src --ext .ts",
|
||||
"test": "vitest run"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tinywaste/game-core": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { applyGameAction, buildGameView, createNewGameState } from '@tinywaste/game-core';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { gameContent } from './index';
|
||||
|
||||
describe('TinyWaste gameplay loop', () => {
|
||||
it('creates a new survivor at the shelter with a starter loadout', () => {
|
||||
const state = createNewGameState(gameContent, '测试幸存者');
|
||||
|
||||
expect(state.player.placeId).toBe('home');
|
||||
expect(state.player.inventory.some((entry) => entry.itemId === 'shiv')).toBe(true);
|
||||
expect(state.player.quests.q_tutorial_water.state).toBe('active');
|
||||
});
|
||||
|
||||
it('collects rain water and advances time when performing the base scavenging action', () => {
|
||||
const state = createNewGameState(gameContent, '测试幸存者');
|
||||
const initialWater = state.player.inventory.find((entry) => entry.itemId === 'water_dirty')?.count ?? 0;
|
||||
const initialMinutes = state.world.time.totalMinutes;
|
||||
|
||||
const result = applyGameAction(state, gameContent, {
|
||||
type: 'perform-action',
|
||||
actionId: 'home_rain_barrel',
|
||||
});
|
||||
|
||||
const currentWater = result.state.player.inventory.find((entry) => entry.itemId === 'water_dirty')?.count ?? 0;
|
||||
|
||||
expect(result.state.world.time.totalMinutes).toBeGreaterThan(initialMinutes);
|
||||
expect(currentWater).toBeGreaterThan(initialWater);
|
||||
expect(result.state.world.logs.at(-1)?.message).toContain('浑水');
|
||||
});
|
||||
|
||||
it('updates the current place after travel and exposes the new location in the game view', () => {
|
||||
const state = createNewGameState(gameContent, '测试幸存者');
|
||||
const initialView = buildGameView(state, gameContent);
|
||||
|
||||
const result = applyGameAction(state, gameContent, {
|
||||
type: 'travel',
|
||||
toPlaceId: initialView.map.edges[0]?.to ?? 'roadside',
|
||||
});
|
||||
const view = buildGameView(result.state, gameContent);
|
||||
|
||||
expect(result.state.player.placeId).toBe('roadside');
|
||||
expect(view.header.placeName).toBe('近郊土路');
|
||||
expect(view.map.places.find((place) => place.current)?.id).toBe('roadside');
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user