Modding:Guía del Modder/Fundamentos del juego
- Introducción
- Fundamentos del juego
- Prueba y solución de problemas
- Lanzamiento
- Referencias API
- APIs de SMAPI Básicas:
- APIs de SMAPI Avanzadas:
- Guías específicos
Esta página explica algunos de los fundamentos de Stardew Valley que son útiles para los modders. Ver también Modding:Tareas comunes.
Conceptos
Baldosas
El mundo se presenta como una cuadrícula de baldosas. Cada baldosa tiene una coordenada (x, y) que representa su posición en el mapa, donde (0, 0) es el mosaico superior izquierdo. El valor de x aumenta hacia la derecha y el de y aumenta hacia abajo. Por ejemplo:
Posiciones
El juego utiliza tres sistemas de coordenadas relacionados:
sistema de coordenadas | relativo a | notas |
---|---|---|
posición de la baldosa | esquina superior izquierda del mapa | medido en baldosas; se utiliza al colocar cosas en el mapap (p.ej., location.Objects utiliza posiciones de la baldosa). |
posición absoluta | esquina superior izquierda del mapa | medido en píxeles; se usa cuando se necesitan mediciones más granulares (p.ej., movimiento del NPC). |
posición de la pantalla | esquina superior izquierda visible de la pantalla | medido en píxeles; se utiliza al dibujar en la pantalla. |
He aquí cómo convertir entre ellos:
conversión | fórmula | ||
---|---|---|---|
absoluta | → | pantalla | x - Game1.viewport.X, y - Game1.viewport.Y
|
absoluta | → | baldosa | x / Game1.tileSize, y / Game1.tileSize
|
pantalla | → | absoluta | x + Game1.viewport.X, y + Game1.viewport.Y
|
pantalla | → | baldosa | (x + Game1.viewport.X) / Game1.tileSize, (y + Game1.viewport.Y) / Game1.tileSize
|
baldosa | → | absoluta | x * Game1.tileSize, y * Game1.tileSize
|
baldosa | → | pantalla | (x * Game1.tileSize) - Game1.viewport.X, (y * Game1.tileSize) - Game1.viewport.Y
|
Campos de red
Un 'tipo de red' es cualquiera de varias clases que Stardew Valley usa para sincronizar datos entre jugadores, y un 'campo de red' es cualquier campo o propiedad de esos tipos. Se nombran por el Net
prefijo en sus nombres de tipo. Los tipos de red pueden representar valores simples como NetBool, o valores complejos como NetFieldDictionary. El juego recolectará regularmente todos los campos netos accesibles desde Game1.netWorldState y sincronizarlos con otros jugadores. Eso significa que muchos cambios de mod se sincronizarán automáticamente en el modo multijugador.
Aunque los campos netos se pueden convertir implícitamente a un tipo de valor equivalente (como bool x = new NetBool(true)
), sus reglas de conversión son contrarias a la intuición y propensas a errores (p.ej., item?.category == null && item?.category != null
ambos pueden ser verdaderos a la vez). Para evitar errores, nunca emita implícitamente campos de red; acceda al valor subyacente directamente en su lugar. El paquete NuGet de configuración de compilación debe detectar la mayoría de las conversiones implícitas y mostrar una advertencia de compilación adecuada.
Aquí se explica cómo acceder a los datos en algunos tipos de red comunes:
tipo de red | descripción |
---|---|
NetBool NetColor NetFloat NetInt NetPoint NetString |
Un valor sincronizado simple. Acceda al valor usando field.Value. |
NetCollection<T> NetList<T> NetObjectList<T> |
Una lista de valores T. Esto implementa las interfaces estándar como IEnumerable<T> y IList<T>, por lo que puede iterarlo directamente como el foreach (T el valor en el campo) .
|
NetLongDictionary<TValue, TNetValue> NetPointDictionary<TValue, TNetValue> NetVector2Dictionary<TValue, TNetValue> |
Mapas Long, Point, o Vector2 para instancias de TValue (el tipo de valor subyacente) y TNetValue (el tipo de red sincronizada). Puede iterar llaves/valor en pares como el foreach (KeyValuePair<Long, TValue> pair in field.Pairs) (reemplazando Long con Point o Vector2 si es necesario).
|
Nivel del zoom
El jugador puede establecer un nivel de zoom en el juego entre 75% y 200%, que ajusta el tamaño de todos los píxeles que se muestran en la pantalla. Por ejemplo, aquí hay un reproductor con el mismo tamaño de ventana en diferentes niveles de zoom:
nivel mínimo de zoom (75%) | nivel máximo de zoom (200%) |
---|---|
- Efecto en los mods de SMAPI
- En el código del juego, esto está representado por el campo Game1.options.zoomLevel. Las coordenadas generalmente se ajustan para el nivel de zoom automáticamente, por lo que rara vez necesita tener esto en cuenta; pero puede convertir una coordenada no ajustada usando
position * (1f / Game1.options.zoomLevel)
si es necesario.
Escalado del IU
El jugador puede escalar la interfaz de usuario entre un 75 % y un 150 %, por separado y junto al nivel del zoom. Eso ajusta el tamaño de los píxeles que se muestran en la pantalla solo para los elementos de la interfaz de usuario. Por ejemplo, aquí hay un reproductor con el mismo tamaño de ventana en diferentes niveles de escala de IU:
escala mínima de IU (75 %) | escala máxima de IU (150%) |
---|---|
- Efecto en los mods de SMAPI
- El juego tiene dos modos de escala distintos según el contexto: modo de interfaz de usuario y modo sin interfaz de usuario. Puedes comprobar Game1.uiMode para saber qué modo está activo. Debe tener cuidado de no mezclar coordenadas de IU y no IU para evitar cálculos complicados; por ejemplo, haga todo su trabajo en un sistema de coordenadas y luego conviértalo una vez.
- Una referencia rápida de escenarios comunes:
contexto modo de la escala que se aplica menús en los que se puede hacer click Modo de interfaz de usuario (generalmente) elementos del HUD modo de interfaz de usuario RenderingActiveMenu
RenderedActiveMenumodo de interfaz de usuario Rendering
Rendereddepende del contexto; chequear en Game1.uiMode draw método para objetos del mundo modo sin interfaz de usuario coordenadas de la baldosa (sin píxeles) no se ve afectado por la escala de la interfaz de usuario
- Si necesita dibujar la interfaz de usuario cuando el juego no está en modo de interfaz de usuario, puede establecer explícitamente el modo de escalado de interfaz de usuario:
Game1.game1.InUIMode(() => { // su código de dibujo de UI aquí });
- En el modo de interfaz de usuario, normalmente debe reemplazar Game1.viewport con Game1.uiViewport. No haga esto si va a ajustar las posiciones para el escalado de la interfaz de usuario por separado, ya que la conversión doble le dará resultados incorrectos. Puede convertir entre coordenadas UI y no UI usando Utility.ModifyCoordinatesForUIScale y Utility.ModifyCoordinatesFromUIScale.
- Puedes probar si tu mod tiene en cuenta esto correctamente ajustando el zoom al máximo y la escala de la interfaz de usuario al mínimo (es decir., teniéndolos en valores opuestos) o viceversa; en particular, verifique cualquier lógica que maneje las posiciones de los píxeles, como hacer clic en los menús.
Accesos
Llaves de cadena
Una llave de cadena identifica de forma única dónde encontrar texto traducible, en la forma <asset name>
:<key>
. Por ejemplo, Game1.content.GetString("Strings\\StringsFromCSFiles:spring")
buscará un spring llave en Strings\StringsFromCSFiles archivo en la carpeta de contenido (que contiene "primavera"). Esto se usa comúnmente en el código del juego (a través de Game1.content.GetString
y en los activos de datos que necesitan texto traducible.
Clases principales
Game1
Game1 es la lógica central del juego. La mayor parte del estado del juego se rastrea a través de esta clase. Estos son algunos de los campos más útiles:
campo | tipo | propósito |
---|---|---|
Game1.player | Farmer | El jugador actual. |
Game1.currentLocation | GameLocation | La ubicación del juego que contiene al jugador actual. Para un jugador no principal, puede ser null al hacer la transición entre ubicaciones. |
Game1.locations | IList<GameLocation> | Todas las ubicaciones del juego. Para un jugador no principal, use el metodo SMAPI's GetActiveLocations en su lugar. |
Game1.timeOfDay Game1.dayOfMonth Game1.currentSeason Game1.year |
int int string int |
La hora, el día, la estación y el año actuales. Consulte también la utilidad de fecha de SMAPI. |
Game1.itemsToShip | IList<Item> | No usar (esto es parte de la lógica de guardado). Ver Game1.getFarm().getShippingBin(Farmer) en su lugar. |
Game1.activeClickableMenu | IClickableMenu | El menú modales que se muestra. Creando un IClickableMenu subclase y asignar una instancia a este campo lo mostrará. |
GameLocation y otros
- GameLocation representa una ubicación en el juego que los jugadores pueden visitar. Cada ubicación tiene un mapa (el diseño de mosaico), objetos, árboles, personajes, etc. Estos son algunos de los campos más útiles para cualquier ubicación:
campo tipo propósito Name string El nombre único para esta ubicación. (Esto no es único para interiores de edificios construidos como cabañas; consulte uniqueName en su lugar.) IsFarm bool Si se trata de una granja, donde se pueden plantar cultivos. IsGreenhouse bool Si se trata de un invernadero, donde se pueden plantar y cultivar cultivos durante todo el año. IsOutdoors bool Si la ubicación es al aire libre (a diferencia de un invernadero, edificio, etc.). characters NetCollection de NPC Los aldeanos, las mascotas, los caballos y los monstruos del lugar. critters List of Critter Los pájaros, ardillas u otros bichos temporales en el lugar. debris NetCollection de Debris Los elementos flotantes en la ubicación. farmers FarmerCollection Los jugadores en el ubicación. Objects OverlaidDictionary Las cercas colocadas, las máquinas de artesanía y otros objetos en la ubicación actual. (OverlaidDictionary básicamente un NetVector2Dictionary con lógica agregada para mostrar ciertos elementos de búsqueda sobre objetos preexistentes). terrainFeatures NetVector2Dictionary de TerrainFeature Los árboles, árboles frutales, hierba alta, tierra cultivada (incluyendo cultivos) y pisos en el lugar. Para cada par, la clave es su posición de mosaico y el valor es la instancia de la característica del terreno. waterTiles bool[,] Una matriz multidimensional que indica si cada baldosa en el mapa es un baldosas de lago/río. Por ejemplo, if (location.waterTiles[10, 20])
comprueba la baldosa en la posición (10, 20). - BuildableGameLocation es una subclase de BuildableGame para lugares donde los jugadores pueden construir edificios. En el juego de vainilla, solo la granja es un lugar edificable. Estos son los campos más útiles:
campo tipo propósito buildings NetCollection de Building Los edificios en el lugar. - Farm es una subclase de ambos GameLocation and BuildableGameLocation del juego para construirpara lugares donde el jugador puede tener animales y cultivar. En Vanilla, solo hay una ubicación de granja (a la que se accede mediante
Game1.getFarm()
). Estas son sus propiedades más útiles:campo tipo propósito animals NetLongDictionary de FarmAnimal os animales de granja actualmente en el lugar. resourceClumps NetCollection de ResourceClump Los cultivos gigantes, tocones grandes, rocas y meteoritos en el lugar. piecesOfHay NetInt La cantidad de heno almacenado en silos. shippingBin NetCollection de Item Los artículos en el contenedor de envío. - Hay una serie de subclases para una ubicación específica (como AdventureGuild) que tienen campos útiles para casos específicos.