Compare commits
4
Commits
ca54c8c965
...
v1.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f91de4ccfd | ||
|
|
4fdc52fcd1 | ||
|
|
019810615a | ||
|
|
c9f2f221ba |
+23
@@ -0,0 +1,23 @@
|
|||||||
|
# Privacy Policy
|
||||||
|
|
||||||
|
LCDPet is an offline/local-first Android app.
|
||||||
|
|
||||||
|
## Data collection
|
||||||
|
|
||||||
|
LCDPet does not collect, transmit, sell, or share personal data.
|
||||||
|
|
||||||
|
## Network access
|
||||||
|
|
||||||
|
LCDPet does not request internet permission and does not connect to external servers.
|
||||||
|
|
||||||
|
## Local storage
|
||||||
|
|
||||||
|
LCDPet stores pet progress locally on the device.
|
||||||
|
|
||||||
|
## Notifications
|
||||||
|
|
||||||
|
LCDPet may request notification permission on supported Android versions. Notifications are used only for local pet care reminders.
|
||||||
|
|
||||||
|
## Third-party services
|
||||||
|
|
||||||
|
LCDPet does not use analytics, advertising SDKs, trackers, cloud services, or account systems.
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# LCDPet
|
||||||
|
|
||||||
|
LCDPet is a tiny offline LCD-style virtual pet for Android.
|
||||||
|
|
||||||
|
It is designed to feel like a simple handheld digital pet: feed your pet, bathe it, let it nap, take it outside, handle Wants, and keep an eye on its care status.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Starter pet templates
|
||||||
|
- Offline/local-first virtual pet
|
||||||
|
- LCD-style toy-inspired interface
|
||||||
|
- Care actions: feed, bathe, nap, walk, potty, pet, and talk
|
||||||
|
- Random Wants and care reminders
|
||||||
|
- Optional Android notifications for pet care alerts
|
||||||
|
- No ads
|
||||||
|
- No tracking
|
||||||
|
- No internet permission
|
||||||
|
- No gameplay purchases or pay-to-win mechanics
|
||||||
|
|
||||||
|
## Privacy
|
||||||
|
|
||||||
|
LCDPet stores pet data locally on your device.
|
||||||
|
|
||||||
|
It does not use internet access, analytics, advertising SDKs, trackers, accounts, cloud sync, or external servers.
|
||||||
|
|
||||||
|
The notification permission is used only for local pet care reminders.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
LCDPet is licensed under the GNU General Public License v3.0.
|
||||||
|
|
||||||
|
See [LICENSE](LICENSE) for details.
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
Audio credits and license/source notes are included inside the app under:
|
||||||
|
|
||||||
|
`Credits / Licenses`
|
||||||
|
|
||||||
|
The audio credits source file is:
|
||||||
|
|
||||||
|
`app/src/main/assets/audio_credits.txt`
|
||||||
@@ -72,6 +72,75 @@ private data class CareJournalEntry(
|
|||||||
val happenedAtMs: Long
|
val happenedAtMs: Long
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private data class PetTemplate(
|
||||||
|
val id: String,
|
||||||
|
val label: String,
|
||||||
|
val topLine: String,
|
||||||
|
val facePrefix: String,
|
||||||
|
val faceSuffix: String,
|
||||||
|
val feetLine: String
|
||||||
|
)
|
||||||
|
|
||||||
|
private val lcdPetTemplates = listOf(
|
||||||
|
PetTemplate(
|
||||||
|
id = "classic",
|
||||||
|
label = "Classic",
|
||||||
|
topLine = " /---\\ \n",
|
||||||
|
facePrefix = "( ",
|
||||||
|
faceSuffix = " )\n",
|
||||||
|
feetLine = " /| |\\ "
|
||||||
|
),
|
||||||
|
PetTemplate(
|
||||||
|
id = "scruffy",
|
||||||
|
label = "Scruffy",
|
||||||
|
topLine = " /^^^\\ \n",
|
||||||
|
facePrefix = "( ",
|
||||||
|
faceSuffix = " )\n",
|
||||||
|
feetLine = " /|_|\\ "
|
||||||
|
),
|
||||||
|
PetTemplate(
|
||||||
|
id = "bean",
|
||||||
|
label = "Round Bean",
|
||||||
|
topLine = " .---. \n",
|
||||||
|
facePrefix = "( ",
|
||||||
|
faceSuffix = " )\n",
|
||||||
|
feetLine = " /|\\ "
|
||||||
|
),
|
||||||
|
PetTemplate(
|
||||||
|
id = "pocketpup",
|
||||||
|
label = "Pocket Pup",
|
||||||
|
topLine = " /\\_/\\ \n",
|
||||||
|
facePrefix = "( ",
|
||||||
|
faceSuffix = " )\n",
|
||||||
|
feetLine = " /|\\ "
|
||||||
|
),
|
||||||
|
PetTemplate(
|
||||||
|
id = "batty",
|
||||||
|
label = "Batty",
|
||||||
|
topLine = "/\\---/\\\n",
|
||||||
|
facePrefix = "( ",
|
||||||
|
faceSuffix = " )\n",
|
||||||
|
feetLine = " /|\\ "
|
||||||
|
),
|
||||||
|
PetTemplate(
|
||||||
|
id = "goblin",
|
||||||
|
label = "Goblin",
|
||||||
|
topLine = " /\\_/\\ \n",
|
||||||
|
facePrefix = "( ",
|
||||||
|
faceSuffix = " )\n",
|
||||||
|
feetLine = " /| |\\ "
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun lcdPetTemplateById(id: String): PetTemplate {
|
||||||
|
return lcdPetTemplates.firstOrNull { it.id == id } ?: lcdPetTemplates.first()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun renderPetTemplateText(template: PetTemplate, expression: String): String {
|
||||||
|
return template.topLine + template.facePrefix + expression + template.faceSuffix + template.feetLine
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -376,6 +445,8 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
|||||||
var pottyFaceBag by remember { mutableStateOf(emptyList<String>()) }
|
var pottyFaceBag by remember { mutableStateOf(emptyList<String>()) }
|
||||||
var petName by remember { mutableStateOf("") }
|
var petName by remember { mutableStateOf("") }
|
||||||
var pendingPetName by remember { mutableStateOf("") }
|
var pendingPetName by remember { mutableStateOf("") }
|
||||||
|
var petTemplateId by remember { mutableStateOf("classic") }
|
||||||
|
var pendingPetTemplateId by remember { mutableStateOf("classic") }
|
||||||
var happyOutsideTrip by remember { mutableStateOf(false) }
|
var happyOutsideTrip by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
var petAgeDays by remember { mutableIntStateOf(0) }
|
var petAgeDays by remember { mutableIntStateOf(0) }
|
||||||
@@ -583,6 +654,8 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
|||||||
currentWant = save.currentWant
|
currentWant = save.currentWant
|
||||||
petName = save.petName
|
petName = save.petName
|
||||||
pendingPetName = save.petName
|
pendingPetName = save.petName
|
||||||
|
petTemplateId = save.petTemplateId.ifBlank { "classic" }
|
||||||
|
pendingPetTemplateId = petTemplateId
|
||||||
isSleeping = save.isSleeping
|
isSleeping = save.isSleeping
|
||||||
sleepMode = save.sleepMode
|
sleepMode = save.sleepMode
|
||||||
roughWakeAlert = save.roughWakeAlert
|
roughWakeAlert = save.roughWakeAlert
|
||||||
@@ -648,7 +721,7 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
|||||||
|
|
||||||
val petAgeText = statAgeText(petAgeDays)
|
val petAgeText = statAgeText(petAgeDays)
|
||||||
val displayPetName = petName.ifBlank { "Pet" }
|
val displayPetName = petName.ifBlank { "Pet" }
|
||||||
val needsPetName = saveLoaded && petName.isBlank() && !isTradingInPet && !isFindingNewPet
|
val needsPetName = saveLoaded && (petName.isBlank() || petTemplateId.isBlank()) && !isTradingInPet && !isFindingNewPet
|
||||||
val trimmedPendingPetName = pendingPetName.trim()
|
val trimmedPendingPetName = pendingPetName.trim()
|
||||||
val normalizedPendingPetName = trimmedPendingPetName.lowercase()
|
val normalizedPendingPetName = trimmedPendingPetName.lowercase()
|
||||||
val isNameValidationActive = !testingMode
|
val isNameValidationActive = !testingMode
|
||||||
@@ -656,6 +729,8 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
|||||||
val isReservedPetName = isNameValidationActive && normalizedPendingPetName in reservedPetNames
|
val isReservedPetName = isNameValidationActive && normalizedPendingPetName in reservedPetNames
|
||||||
val hasValidPetNameLetters = trimmedPendingPetName.isNotEmpty() && trimmedPendingPetName.all { it.isLetter() }
|
val hasValidPetNameLetters = trimmedPendingPetName.isNotEmpty() && trimmedPendingPetName.all { it.isLetter() }
|
||||||
val canKeepPetName = hasValidPetNameLetters && !isReservedPetName
|
val canKeepPetName = hasValidPetNameLetters && !isReservedPetName
|
||||||
|
val pendingPetTemplate = lcdPetTemplateById(pendingPetTemplateId)
|
||||||
|
val selectedPetTemplate = lcdPetTemplateById(petTemplateId)
|
||||||
|
|
||||||
val bondRelationship = when {
|
val bondRelationship = when {
|
||||||
bond >= 100 -> "BFF"
|
bond >= 100 -> "BFF"
|
||||||
@@ -796,13 +871,13 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val petArt = buildAnnotatedString {
|
val petArt = buildAnnotatedString {
|
||||||
append(" /---\\ \n")
|
append(selectedPetTemplate.topLine)
|
||||||
append("( ")
|
append(selectedPetTemplate.facePrefix)
|
||||||
withStyle(SpanStyle(fontWeight = if (pottyFaceOverride.isNotEmpty()) FontWeight.Bold else FontWeight.Normal)) {
|
withStyle(SpanStyle(fontWeight = if (pottyFaceOverride.isNotEmpty()) FontWeight.Bold else FontWeight.Normal)) {
|
||||||
append(petExpression)
|
append(petExpression)
|
||||||
}
|
}
|
||||||
append(" )\n")
|
append(selectedPetTemplate.faceSuffix)
|
||||||
append(" /| |\\ ")
|
append(selectedPetTemplate.feetLine)
|
||||||
}
|
}
|
||||||
|
|
||||||
val petColor = if (status == "Sick") sickGreen else lcdDark
|
val petColor = if (status == "Sick") sickGreen else lcdDark
|
||||||
@@ -1343,6 +1418,8 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
|||||||
careJournalEntries = emptyList()
|
careJournalEntries = emptyList()
|
||||||
petName = ""
|
petName = ""
|
||||||
pendingPetName = ""
|
pendingPetName = ""
|
||||||
|
petTemplateId = "classic"
|
||||||
|
pendingPetTemplateId = "classic"
|
||||||
happyOutsideTrip = false
|
happyOutsideTrip = false
|
||||||
petAgeDays = 0
|
petAgeDays = 0
|
||||||
careScore = 0
|
careScore = 0
|
||||||
@@ -1397,6 +1474,7 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
|||||||
tradeInProgress = 0,
|
tradeInProgress = 0,
|
||||||
currentWant = currentWant,
|
currentWant = currentWant,
|
||||||
petName = petName,
|
petName = petName,
|
||||||
|
petTemplateId = petTemplateId,
|
||||||
isSleeping = isSleeping,
|
isSleeping = isSleeping,
|
||||||
sleepMode = sleepMode,
|
sleepMode = sleepMode,
|
||||||
roughWakeAlert = roughWakeAlert,
|
roughWakeAlert = roughWakeAlert,
|
||||||
@@ -1438,6 +1516,7 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
|||||||
tradeInProgress = 0,
|
tradeInProgress = 0,
|
||||||
currentWant = currentWant,
|
currentWant = currentWant,
|
||||||
petName = petName,
|
petName = petName,
|
||||||
|
petTemplateId = petTemplateId,
|
||||||
isSleeping = isSleeping,
|
isSleeping = isSleeping,
|
||||||
sleepMode = sleepMode,
|
sleepMode = sleepMode,
|
||||||
roughWakeAlert = roughWakeAlert,
|
roughWakeAlert = roughWakeAlert,
|
||||||
@@ -1652,6 +1731,7 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
|||||||
tradeInProgress = tradeInProgress,
|
tradeInProgress = tradeInProgress,
|
||||||
currentWant = currentWant,
|
currentWant = currentWant,
|
||||||
petName = petName,
|
petName = petName,
|
||||||
|
petTemplateId = petTemplateId,
|
||||||
isSleeping = isSleeping,
|
isSleeping = isSleeping,
|
||||||
sleepMode = sleepMode,
|
sleepMode = sleepMode,
|
||||||
roughWakeAlert = roughWakeAlert,
|
roughWakeAlert = roughWakeAlert,
|
||||||
@@ -1700,6 +1780,7 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
|||||||
tradeInProgress = tradeInProgressBlocks,
|
tradeInProgress = tradeInProgressBlocks,
|
||||||
currentWant = currentWant,
|
currentWant = currentWant,
|
||||||
petName = petName,
|
petName = petName,
|
||||||
|
petTemplateId = petTemplateId,
|
||||||
isSleeping = isSleeping,
|
isSleeping = isSleeping,
|
||||||
sleepMode = sleepMode,
|
sleepMode = sleepMode,
|
||||||
roughWakeAlert = roughWakeAlert,
|
roughWakeAlert = roughWakeAlert,
|
||||||
@@ -2310,6 +2391,7 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
|||||||
tradeInProgress = tradeInProgress,
|
tradeInProgress = tradeInProgress,
|
||||||
currentWant = currentWant,
|
currentWant = currentWant,
|
||||||
petName = petName,
|
petName = petName,
|
||||||
|
petTemplateId = petTemplateId,
|
||||||
isSleeping = true,
|
isSleeping = true,
|
||||||
sleepMode = "Auto",
|
sleepMode = "Auto",
|
||||||
roughWakeAlert = roughWakeAlert,
|
roughWakeAlert = roughWakeAlert,
|
||||||
@@ -2470,7 +2552,75 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
|||||||
verticalArrangement = Arrangement.spacedBy(6.dp)
|
verticalArrangement = Arrangement.spacedBy(6.dp)
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = "NAME NEW PET",
|
text = "CHOOSE NEW PET",
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "PET TEMPLATE",
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "Selected: ${pendingPetTemplate.label}",
|
||||||
|
color = lcdDark,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
|
||||||
|
lcdPetTemplates.chunked(2).forEach { rowTemplates ->
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(6.dp)
|
||||||
|
) {
|
||||||
|
rowTemplates.forEach { template ->
|
||||||
|
val isSelectedTemplate = pendingPetTemplateId == template.id
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.border(
|
||||||
|
width = if (isSelectedTemplate) 2.dp else 1.dp,
|
||||||
|
color = if (isSelectedTemplate) lcdDark else lcdFaded
|
||||||
|
)
|
||||||
|
.clickable {
|
||||||
|
pendingPetTemplateId = template.id
|
||||||
|
}
|
||||||
|
.padding(vertical = 4.dp, horizontal = 2.dp),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = renderPetTemplateText(template, "^_^"),
|
||||||
|
fontSize = 11.sp,
|
||||||
|
lineHeight = 11.sp,
|
||||||
|
fontFamily = FontFamily.Monospace,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
color = lcdDark
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = template.label.uppercase(),
|
||||||
|
fontSize = 10.sp,
|
||||||
|
lineHeight = 10.sp,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
color = lcdDark
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "NAME PET",
|
||||||
fontWeight = FontWeight.Bold,
|
fontWeight = FontWeight.Bold,
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
modifier = Modifier.fillMaxWidth()
|
modifier = Modifier.fillMaxWidth()
|
||||||
@@ -2522,6 +2672,7 @@ fun Greeting(name: String, modifier: Modifier = Modifier) {
|
|||||||
lcdDark = lcdDark,
|
lcdDark = lcdDark,
|
||||||
lcdFaded = lcdFaded,
|
lcdFaded = lcdFaded,
|
||||||
onClick = {
|
onClick = {
|
||||||
|
petTemplateId = pendingPetTemplateId
|
||||||
petName = trimmedPendingPetName.take(12)
|
petName = trimmedPendingPetName.take(12)
|
||||||
pendingPetName = petName
|
pendingPetName = petName
|
||||||
statsMenuOpen = false
|
statsMenuOpen = false
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ data class LCDPetRecordSave(
|
|||||||
val tradeInProgress: Int = 0,
|
val tradeInProgress: Int = 0,
|
||||||
val currentWant: String = "",
|
val currentWant: String = "",
|
||||||
val petName: String = "",
|
val petName: String = "",
|
||||||
|
val petTemplateId: String = "classic",
|
||||||
val isSleeping: Boolean = false,
|
val isSleeping: Boolean = false,
|
||||||
val sleepMode: String = "",
|
val sleepMode: String = "",
|
||||||
val roughWakeAlert: Boolean = false,
|
val roughWakeAlert: Boolean = false,
|
||||||
@@ -66,6 +67,7 @@ private object LCDPetSaveKeys {
|
|||||||
val TRADE_IN_PROGRESS = intPreferencesKey("trade_in_progress")
|
val TRADE_IN_PROGRESS = intPreferencesKey("trade_in_progress")
|
||||||
val CURRENT_WANT = stringPreferencesKey("current_want")
|
val CURRENT_WANT = stringPreferencesKey("current_want")
|
||||||
val PET_NAME = stringPreferencesKey("pet_name")
|
val PET_NAME = stringPreferencesKey("pet_name")
|
||||||
|
val PET_TEMPLATE_ID = stringPreferencesKey("pet_template_id")
|
||||||
val IS_SLEEPING = booleanPreferencesKey("is_sleeping")
|
val IS_SLEEPING = booleanPreferencesKey("is_sleeping")
|
||||||
val SLEEP_MODE = stringPreferencesKey("sleep_mode")
|
val SLEEP_MODE = stringPreferencesKey("sleep_mode")
|
||||||
val ROUGH_WAKE_ALERT = booleanPreferencesKey("rough_wake_alert")
|
val ROUGH_WAKE_ALERT = booleanPreferencesKey("rough_wake_alert")
|
||||||
@@ -99,6 +101,7 @@ val Context.lcdPetRecordSaveFlow: Flow<LCDPetRecordSave>
|
|||||||
tradeInProgress = preferences[LCDPetSaveKeys.TRADE_IN_PROGRESS] ?: 0,
|
tradeInProgress = preferences[LCDPetSaveKeys.TRADE_IN_PROGRESS] ?: 0,
|
||||||
currentWant = preferences[LCDPetSaveKeys.CURRENT_WANT] ?: "",
|
currentWant = preferences[LCDPetSaveKeys.CURRENT_WANT] ?: "",
|
||||||
petName = preferences[LCDPetSaveKeys.PET_NAME] ?: "",
|
petName = preferences[LCDPetSaveKeys.PET_NAME] ?: "",
|
||||||
|
petTemplateId = preferences[LCDPetSaveKeys.PET_TEMPLATE_ID] ?: "classic",
|
||||||
isSleeping = preferences[LCDPetSaveKeys.IS_SLEEPING] ?: false,
|
isSleeping = preferences[LCDPetSaveKeys.IS_SLEEPING] ?: false,
|
||||||
sleepMode = preferences[LCDPetSaveKeys.SLEEP_MODE] ?: "",
|
sleepMode = preferences[LCDPetSaveKeys.SLEEP_MODE] ?: "",
|
||||||
roughWakeAlert = preferences[LCDPetSaveKeys.ROUGH_WAKE_ALERT] ?: false,
|
roughWakeAlert = preferences[LCDPetSaveKeys.ROUGH_WAKE_ALERT] ?: false,
|
||||||
@@ -131,6 +134,7 @@ suspend fun Context.saveLCDPetStats(
|
|||||||
tradeInProgress: Int,
|
tradeInProgress: Int,
|
||||||
currentWant: String,
|
currentWant: String,
|
||||||
petName: String,
|
petName: String,
|
||||||
|
petTemplateId: String = "classic",
|
||||||
isSleeping: Boolean,
|
isSleeping: Boolean,
|
||||||
sleepMode: String,
|
sleepMode: String,
|
||||||
roughWakeAlert: Boolean,
|
roughWakeAlert: Boolean,
|
||||||
@@ -160,6 +164,7 @@ suspend fun Context.saveLCDPetStats(
|
|||||||
preferences[LCDPetSaveKeys.TRADE_IN_PROGRESS] = tradeInProgress
|
preferences[LCDPetSaveKeys.TRADE_IN_PROGRESS] = tradeInProgress
|
||||||
preferences[LCDPetSaveKeys.CURRENT_WANT] = currentWant
|
preferences[LCDPetSaveKeys.CURRENT_WANT] = currentWant
|
||||||
preferences[LCDPetSaveKeys.PET_NAME] = petName
|
preferences[LCDPetSaveKeys.PET_NAME] = petName
|
||||||
|
preferences[LCDPetSaveKeys.PET_TEMPLATE_ID] = petTemplateId
|
||||||
preferences[LCDPetSaveKeys.IS_SLEEPING] = isSleeping
|
preferences[LCDPetSaveKeys.IS_SLEEPING] = isSleeping
|
||||||
preferences[LCDPetSaveKeys.SLEEP_MODE] = sleepMode
|
preferences[LCDPetSaveKeys.SLEEP_MODE] = sleepMode
|
||||||
preferences[LCDPetSaveKeys.ROUGH_WAKE_ALERT] = roughWakeAlert
|
preferences[LCDPetSaveKeys.ROUGH_WAKE_ALERT] = roughWakeAlert
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
Initial v1.0 release candidate.
|
||||||
|
|
||||||
|
Adds starter pet templates, the core LCDPet care loop, local save/load, Wants, care status tracking, optional local notifications, Credits / Licenses screen, and offline-first Android gameplay.
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
LCDPet is a tiny offline LCD-style virtual pet for Android.
|
||||||
|
|
||||||
|
Feed your pet, bathe it, let it nap, take it outside, handle random Wants, and keep an eye on its care status. The app is designed around a simple handheld digital-pet feel with local progress, toy-like interactions, and a low-pressure care loop.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
* Starter pet templates
|
||||||
|
|
||||||
|
* Offline/local-first virtual pet
|
||||||
|
* LCD-style toy-inspired interface
|
||||||
|
* Care actions including feed, bathe, nap, walk, potty, pet, and talk
|
||||||
|
* Random Wants and care reminders
|
||||||
|
* Optional Android notifications for local pet care alerts
|
||||||
|
* No ads
|
||||||
|
* No tracking
|
||||||
|
* No internet permission
|
||||||
|
* No gameplay purchases or pay-to-win mechanics
|
||||||
|
|
||||||
|
LCDPet stores pet data locally on your device. It does not use accounts, analytics, advertising SDKs, trackers, cloud sync, or external servers.
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 50 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
@@ -0,0 +1 @@
|
|||||||
|
Tiny offline LCD-style virtual pet for Android
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
LCDPet
|
||||||
Reference in New Issue
Block a user